Date   

[PATCH v9 02/19] ArmPkg/ArmMonitorLib: Definition for ArmMonitorLib library class

PierreGondois
 

From: Pierre Gondois <Pierre.Gondois@...>

The ArmMonitorLib provides an abstract interface to issue
an HyperVisor Call (HVC) or System Monitor Call (SMC) depending
on the default conduit.
The PcdMonitorConduitHvc PCD allows to select the default conduit.

The new library relies on the ArmHvcLib and ArmSmcLib libraries.
A Null instance of these libraries can be used for the unused conduit.

Reviewed-by: Leif Lindholm <quic_llindhol@...>
Signed-off-by: Pierre Gondois <pierre.gondois@...>
---
ArmPkg/ArmPkg.dec | 5 +++
ArmPkg/Include/Library/ArmMonitorLib.h | 42 ++++++++++++++++++++++++++
2 files changed, 47 insertions(+)
create mode 100644 ArmPkg/Include/Library/ArmMonitorLib.h

diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec
index 99cb024d0f93..f17ba913e6de 100644
--- a/ArmPkg/ArmPkg.dec
+++ b/ArmPkg/ArmPkg.dec
@@ -71,6 +71,11 @@ [LibraryClasses.common]
#
ArmSvcLib|Include/Library/ArmSvcLib.h
=20
+ ## @libraryclass Provides a Monitor Call interface that will use the
+ # default conduit (HVC or SMC).
+ #
+ ArmMonitorLib|Include/Library/ArmMonitorLib.h
+
## @libraryclass Provides a default exception handler.
#
DefaultExceptionHandlerLib|Include/Library/DefaultExceptionHandlerLib.=
h
diff --git a/ArmPkg/Include/Library/ArmMonitorLib.h b/ArmPkg/Include/Libr=
ary/ArmMonitorLib.h
new file mode 100644
index 000000000000..d6e13b61d63d
--- /dev/null
+++ b/ArmPkg/Include/Library/ArmMonitorLib.h
@@ -0,0 +1,42 @@
+/** @file
+
+ Copyright (c) 2022, Arm Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef ARM_MONITOR_LIB_H_
+#define ARM_MONITOR_LIB_H_
+
+/** The size of the SMC arguments is different between AArch64 and AArch=
32.
+
+ The native size is used for the arguments.
+ It will be casted to either HVC or SMC args.
+*/
+typedef struct {
+ UINTN Arg0;
+ UINTN Arg1;
+ UINTN Arg2;
+ UINTN Arg3;
+ UINTN Arg4;
+ UINTN Arg5;
+ UINTN Arg6;
+ UINTN Arg7;
+} ARM_MONITOR_ARGS;
+
+/** Monitor call.
+
+ An HyperVisor Call (HVC) or System Monitor Call (SMC) will be issued
+ depending on the default conduit. PcdMonitorConduitHvc determines the =
type
+ of the call: if true, do an HVC.
+
+ @param [in,out] Args Arguments for the HVC/SMC.
+**/
+VOID
+EFIAPI
+ArmMonitorCall (
+ IN OUT ARM_MONITOR_ARGS *Args
+ );
+
+#endif // ARM_MONITOR_LIB_H_
--=20
2.25.1


[PATCH v9 01/19] ArmPkg: PCD to select conduit for monitor calls

PierreGondois
 

From: Sami Mujawar <sami.mujawar@...>

Define a PCD 'PcdMonitorConduitHvc' to select the conduit to use for
monitor calls. PcdMonitorConduitHvc is defined as FALSE by default,
meaning the SMC conduit is enabled as default.

Adding PcdMonitorConduitHvc allows selection of HVC conduit to be used
by virtual firmware implementations.

Reviewed-by: Leif Lindholm <quic_llindhol@...>
Signed-off-by: Pierre Gondois <pierre.gondois@...>
---
ArmPkg/ArmPkg.dec | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec
index cfb6fe602485..99cb024d0f93 100644
--- a/ArmPkg/ArmPkg.dec
+++ b/ArmPkg/ArmPkg.dec
@@ -2,7 +2,7 @@
# ARM processor package.
#
# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
-# Copyright (c) 2011 - 2021, ARM Limited. All rights reserved.
+# Copyright (c) 2011 - 2022, ARM Limited. All rights reserved.
# Copyright (c) 2021, Ampere Computing LLC. All rights reserved.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -134,6 +134,11 @@ [PcdsFeatureFlag.common]
# Define if the GICv3 controller should use the GICv2 legacy
gArmTokenSpaceGuid.PcdArmGicV3WithV2Legacy|FALSE|BOOLEAN|0x00000042
=20
+ ## Define the conduit to use for monitor calls.
+ # Default PcdMonitorConduitHvc =3D FALSE, conduit =3D SMC
+ # If PcdMonitorConduitHvc =3D TRUE, conduit =3D HVC
+ gArmTokenSpaceGuid.PcdMonitorConduitHvc|FALSE|BOOLEAN|0x00000047
+
[PcdsFeatureFlag.ARM]
# Whether to map normal memory as non-shareable. FALSE is the safe cho=
ice, but
# TRUE may be appropriate to fix performance problems if you don't car=
e about
--=20
2.25.1


[PATCH v9 00/19] Add Raw algorithm support using Arm TRNG interface

PierreGondois
 

From: Pierre Gondois <pierre.gondois@...>

Bugzilla: Bug 3668 (https://bugzilla.tianocore.org/show_bug.cgi?id=3D3668=
)

The Arm True Random Number Generator Firmware, Interface 1.0, specificati=
on
defines an interface between an Operating System (OS) executing at EL1 an=
d
Firmware (FW) exposing a conditioned entropy source that is provided by a
TRNG back end.
This patch-set:
- defines an Arm TRNG library class that provides an interface to access
the entropy source on a platform.
- implements an Arm TRNG library instance that uses the Arm FW-TRNG
interface.
- Adds RawAlgorithm support to RngDxe for Arm architecture using the Arm
TRNG interface.
- Enables RNG support using Arm TRNG interface for Kvmtool Guest/Virtual
firmware.

This patch-set is based on the v2 from Sami Mujawar:
[PATCH v2 0/8] Add Raw algorithm support using Arm FW-TRNG interface=20
v2:
https://edk2.groups.io/g/devel/message/83775
v3:
https://edk2.groups.io/g/devel/message/90845
https://github.com/PierreARM/edk2/tree/Arm_Trng_v3
v4:
https://github.com/PierreARM/edk2/tree/Arm_Trng_v4
v5:
https://github.com/PierreARM/edk2/tree/Arm_Trng_v5
v6:
https://github.com/PierreARM/edk2/tree/Arm_Trng_v6
v7:
https://github.com/PierreARM/edk2/tree/Arm_Trng_v7
v8:
https://github.com/PierreARM/edk2/tree/Arm_Trng_v8
v9:
https://github.com/PierreARM/edk2/tree/Arm_Trng_v9

v9:
- Added BaseArmTrngLibNull as default in MdePkg/MdeLibs.dsc.inc. [Liming=
]
- Renamed TrngLib to ArmTrngLib and updated documentation, commit
messages, function names accordingly. [Jiewen, Leif]
v8:
- Added Reviewed-by/Acked-by from Leif on ArmPkg/SecurityPkg
patches. [Leif]
- Renamed FID_TRNG_* macros to ARM_SMC_ID_TRNG_*. [Leif]
v7:
- Removed Reviewed-by from Leif.
- Remove Sami's Signed-off.
V6:
- Added my signed-off on patches authored by Sami. [Leif]
- New patch to make it easier to add new libraries in alphabetical
order: ArmPkg: Sort HVC/SMC section alphbetically in ArmPkg.dsc [Leif]
- Renmaed ArmHvcNullLib to ArmHvcLibNull. [Leif]
- Added RISCV64 to the list of VALID_ARCHITECTURES for BaseTrngLibNull. =
[Leif]
- Removed unnecessary space in function parameter documentation
('[in, out]'). [Rebecca]
- Updated INF_VERSION to latest spec (1.29) for new libraries. [Rebecca]
- Dropped the following patches [Leif]:
- ArmPkg/ArmLib: Add ArmHasRngExt()
- ArmPkg/ArmLib: Add ArmReadIdIsar0() helper
- MdePkg/BaseRngLib: Rename ArmReadIdIsar0() to ArmGetFeatRng()
V5:
- Removed references in Trnglib.h to 'Special Publication'
800-90A and 800-90C, and only reference 'Arm True Random
Number Generator Firmware, Interface 1.0' in the Arm
implementation of the TrngLib. [Jiewen]
V4:
- Removed dependencies on ArmPkg and dropped patch:
[PATCH v3 12/22] SecurityPkg: Update Securitypkg.ci.yaml
[Jiewen]
- Use a dynamically allocated array to hold available algorithms.
The array is freed in a new UNLOAD_IMAGE function and
allocated in arch specific implementations of
GetAvailableAlgorithms(), available in AArch64/AArch64Algo.c
and Arm/ArmAlgo.c.
- Correctly reference gEfiRngAlgorithmSp80090Ctr256Guid
Guid by copying its address (add missing '&'). [Jiewen]
V3:
- Address Leif's comment (moving definitions, optimizations, ...)
- Add ArmMonitorLib to choose Hvc/Smc conduit depending on a Pcd.
- Re-factor some parts of SecurityPkg/RngDxe/ to ease the addition
of new algorithms.
- Add ArmHasRngExt() function to check Arm's FEAT_RNG extension.
V2:
- Updates TrngLib definitions to use RETURN_STATUS as the return type
from the interface functions as TrngLib is base type library.
- Drops the patch "MdePkg: Add definition for NULL GUID" as there is
already an equivalent definition provided by gZeroGuid. Thus, the
use of gNullGuid has been replaced with gZeroGuid.

Pierre Gondois (11):
ArmPkg/ArmMonitorLib: Definition for ArmMonitorLib library class
ArmPkg/ArmMonitorLib: Add ArmMonitorLib
ArmPkg: Sort HVC/SMC section alphbetically in ArmPkg.dsc
ArmPkg/ArmHvcLibNull: Add NULL instance of ArmHvcLib
SecurityPkg/RngDxe: Replace Pcd with Sp80090Ctr256Guid
SecurityPkg/RngDxe: Remove ArchGetSupportedRngAlgorithms()
SecurityPkg/RngDxe: Documentation/include/parameter cleanup
SecurityPkg/RngDxe: Check before advertising Cpu Rng algo
SecurityPkg/RngDxe: Add debug warning for NULL
PcdCpuRngSupportedAlgorithm
SecurityPkg/RngDxe: Rename AArch64/RngDxe.c
SecurityPkg/RngDxe: Add Arm support of RngDxe

Sami Mujawar (8):
ArmPkg: PCD to select conduit for monitor calls
MdePkg/ArmTrngLib: Definition for Arm TRNG library class interface
MdePkg/ArmTrngLib: Add NULL instance of Arm TRNG Library
ArmPkg: Add FID definitions for Arm TRNG
ArmPkg/ArmTrngLib: Add Arm TRNG library
SecurityPkg/RngDxe: Rename RdRandGenerateEntropy to generic name
SecurityPkg/RngDxe: Add AArch64 RawAlgorithm support through
ArmTrngLib
ArmVirtPkg: Kvmtool: Add RNG support using Arm TRNG interface

ArmPkg/ArmPkg.dec | 12 +-
ArmPkg/ArmPkg.dsc | 5 +-
ArmPkg/Include/IndustryStandard/ArmStdSmc.h | 109 ++++-
ArmPkg/Include/Library/ArmMonitorLib.h | 42 ++
ArmPkg/Library/ArmHvcLibNull/ArmHvcLibNull.c | 29 ++
.../Library/ArmHvcLibNull/ArmHvcLibNull.inf | 22 +
ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.c | 34 ++
.../Library/ArmMonitorLib/ArmMonitorLib.inf | 29 ++
ArmPkg/Library/ArmTrngLib/ArmTrngDefs.h | 50 +++
ArmPkg/Library/ArmTrngLib/ArmTrngLib.c | 388 ++++++++++++++++++
ArmPkg/Library/ArmTrngLib/ArmTrngLib.inf | 29 ++
ArmVirtPkg/ArmVirtKvmTool.dsc | 10 +
ArmVirtPkg/ArmVirtKvmTool.fdf | 5 +
MdePkg/Include/Library/ArmTrngLib.h | 106 +++++
.../BaseArmTrngLibNull/BaseArmTrngLibNull.c | 121 ++++++
.../BaseArmTrngLibNull/BaseArmTrngLibNull.inf | 30 ++
.../BaseArmTrngLibNull/BaseArmTrngLibNull.uni | 12 +
MdePkg/MdeLibs.dsc.inc | 1 +
MdePkg/MdePkg.dec | 5 +
MdePkg/MdePkg.dsc | 1 +
.../RngDxe/AArch64/AArch64Algo.c | 72 ++++
.../RngDxe/Arm/ArmAlgo.c | 51 +++
.../RngDxe/{AArch64/RngDxe.c =3D> ArmRngDxe.c} | 81 +++-
.../RandomNumberGenerator/RngDxe/ArmTrng.c | 71 ++++
.../RngDxe/Rand/RdRand.c | 14 +-
.../RngDxe/Rand/RdRand.h | 43 --
.../RngDxe/Rand/RngDxe.c | 62 ++-
.../RandomNumberGenerator/RngDxe/RngDxe.c | 90 ++--
.../RandomNumberGenerator/RngDxe/RngDxe.inf | 18 +-
.../RngDxe/RngDxeInternals.h | 71 ++--
SecurityPkg/SecurityPkg.dsc | 5 +-
31 files changed, 1462 insertions(+), 156 deletions(-)
create mode 100644 ArmPkg/Include/Library/ArmMonitorLib.h
create mode 100644 ArmPkg/Library/ArmHvcLibNull/ArmHvcLibNull.c
create mode 100644 ArmPkg/Library/ArmHvcLibNull/ArmHvcLibNull.inf
create mode 100644 ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.c
create mode 100644 ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.inf
create mode 100644 ArmPkg/Library/ArmTrngLib/ArmTrngDefs.h
create mode 100644 ArmPkg/Library/ArmTrngLib/ArmTrngLib.c
create mode 100644 ArmPkg/Library/ArmTrngLib/ArmTrngLib.inf
create mode 100644 MdePkg/Include/Library/ArmTrngLib.h
create mode 100644 MdePkg/Library/BaseArmTrngLibNull/BaseArmTrngLibNull.=
c
create mode 100644 MdePkg/Library/BaseArmTrngLibNull/BaseArmTrngLibNull.=
inf
create mode 100644 MdePkg/Library/BaseArmTrngLibNull/BaseArmTrngLibNull.=
uni
create mode 100644 SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/AArc=
h64Algo.c
create mode 100644 SecurityPkg/RandomNumberGenerator/RngDxe/Arm/ArmAlgo.=
c
rename SecurityPkg/RandomNumberGenerator/RngDxe/{AArch64/RngDxe.c =3D> A=
rmRngDxe.c} (64%)
create mode 100644 SecurityPkg/RandomNumberGenerator/RngDxe/ArmTrng.c
delete mode 100644 SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.=
h

--=20
2.25.1


Re: [edk2-CCodingStandardsSpecification] Create release/2.30 branch

Michael D Kinney
 

Hi Abner,

Have you reviewed the open BZs against the EDK II C Coding Standard.

Are there any other issues that are considered important to fix before
making a new official release?

Thanks,

Mike

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Chang, Abner via groups.io
Sent: Thursday, October 27, 2022 9:54 AM
To: devel@edk2.groups.io
Cc: Abner Chang <abner.chang@...>
Subject: [edk2-devel] [edk2-CCodingStandardsSpecification] Create release/2.30 branch

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Abner Chang <abner.chang@...>
---
book.json | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/book.json b/book.json
index d112b26..1fdd570 100644
--- a/book.json
+++ b/book.json
@@ -1,8 +1,7 @@
{

"variables" : {

- "draft" : "yes",

"title" : "EDK II C Coding Standards Specification",

- "version" : "Revision 2.2"

+ "version" : "Revision 2.3"

},

"plugins": ["puml-aleung"],

"pluginsConfig": {}

--
2.37.1.windows.1





Re: [PATCH] RedfishPkg/RedfishPlatformCredentialLib: IPMI implementation

Nickle Wang
 

Hi Igor, Abner,

Thanks for your comments. A quick summary as below:

- BIOS is not supported to disable bootstrap credential service. For security purposes, BIOS should shutdown credential service with its internal control mechanism.
- Credential libraries need a cache mechanism to prevent multiple queries to BMC. All applications in BIOS share the same credentials.
- The storage of keeping credentials should be deleted before the end of the DXE event. So that the credential will not be retrieved by unauthorized user or application. (e.g. user can read variable under UEFI shell with dmpstore command)

There is one thing remained and I like to have further discussion. For the authentication method, do we think that client user can decide what authentication method to use regardless of the requirement from server? I am thinking a detection mechanism as below:

Issue HTTP GET to "/redfish/v1/Systems" (which normally require authentication) without authentication method.
a) if client receive 200 OK, "No Auth" is used and we don't need to get credentials
b) if client receive 401 Unauthorized, check the "WWW-Authenticate" field in returned HTTP header. "Basic realm" or "X-Auh-Token realm" or both two methods will be specified. Then client can know what method to use. Two methods all require credential.

Above mechanism can be placed in RedfishCredentailDxe driver so driver will know if it needs to call credential lib or not.

Thanks,
Nickle

-----Original Message-----
From: Igor Kulchytskyy <igork@...>
Sent: Friday, October 28, 2022 9:54 PM
To: Chang, Abner <Abner.Chang@...>; devel@edk2.groups.io; Nickle Wang <nicklew@...>
Cc: Nick Ramirez <nramirez@...>
Subject: RE: [EXTERNAL] RE: [edk2-devel] [PATCH] RedfishPkg/RedfishPlatformCredentialLib: IPMI implementation

External email: Use caution opening links or attachments


Hi Abner,
Yes, you are right that NVRAM variables were deprecated by DMTF.
But we can use our own boot time NVRAM variable to keep FW credentials. That variable will not be accessible from OS, but since we agreed not to disable bootstrap credentials service on exit boot event, then OS may get its own credentials.
Or we can save the credentials in memory variable. But in this case if we have several instances of the library linked with different modules they will have to send their own IPMI command to get credentials.
So, I think it is better to use our own NVRAM boot time variable.
Thank you,
Igor


-----Original Message-----
From: Chang, Abner <Abner.Chang@...>
Sent: Friday, October 28, 2022 3:48 AM
To: devel@edk2.groups.io; Igor Kulchytskyy <igork@...>; nicklew@...
Cc: Nick Ramirez <nramirez@...>
Subject: [EXTERNAL] RE: [edk2-devel] [PATCH] RedfishPkg/RedfishPlatformCredentialLib: IPMI implementation


**CAUTION: The e-mail below is from an external source. Please exercise caution before opening attachments, clicking links, or following guidance.**

[AMD Official Use Only - General]



-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Igor
Kulchytskyy via groups.io
Sent: Thursday, October 27, 2022 10:42 PM
To: devel@edk2.groups.io; nicklew@...; Chang, Abner
<Abner.Chang@...>
Cc: Nick Ramirez <nramirez@...>
Subject: Re: [edk2-devel] [PATCH] RedfishPkg/RedfishPlatformCredentialLib:
IPMI implementation

Caution: This message originated from an External Source. Use proper
caution when opening attachments, clicking links, or responding.


Hi Nickle,
Pleased, see my comments on your questions below.

Another point I missed in my previous mail.
You have that function in the library to get credentials and it is
used by RedfishCredentialsDxe driver to create the protocol which in
its turn will be used by other Redfish modules.
We do not know how many modules and how many times will call this
function during boot. Right?
And on each call of this function you call IPMI command. That command
will create new Redfish account on BMC side according to Redfish HI specification:

" If the Get Bootstrap Account Credentials command has been issued and
responds with the completion code 00h, a bootstrap account shall be
added to the manager's account collection and enabled. If the Get
Bootstrap Account Credentials command is sent subsequent times and
responds with the completion code 00h, a new account shall be created
based on the newly generated credentials. Any existing bootstrap accounts shall remain active."

As I know BMC may have some restrictions on the number of Redfish
accounts they can support.
And because of that BOS may hit this limit. Which is not good.
On the other hand I'm not sure we need to have different credentials
for different modules? All those modules are part of FW. And all of
them will be associated with the same RoleID (FW role) on BMC side.
So, all of them may use the same credentials.
Could we cash the credentials on first call of that
Yes, this is something we have to avoid. Many accounts will be created while each of Redfish client module requests a credential. FW can save it in EFI variable and delete it at proper timing. Unfortunately the credential delivering via EFI variable section was deprecated, otherwise we can deliver the credential to OS through EFI variable with disabling the bootstrap credential at exit boot service.

Abner

RedfishCredentialGetAuthInfo and then use those cashed credentials on
subsequential calls?
It will also may save a boot time, since there is no need to send IPMI
command.

Thank you,
Igor

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Nickle
Wang via groups.io
Sent: Thursday, October 27, 2022 9:26 AM
To: devel@edk2.groups.io; Igor Kulchytskyy <igork@...>;
abner.chang@...
Cc: Nick Ramirez <nramirez@...>
Subject: [EXTERNAL] Re: [edk2-devel] [PATCH]
RedfishPkg/RedfishPlatformCredentialLib: IPMI implementation


**CAUTION: The e-mail below is from an external source. Please
exercise caution before opening attachments, clicking links, or
following guidance.**

Hi Igor,

Thank you for your help to review my changes.

And it will be blocked by our IPMI call.
I see your point. So, BIOS should never be the person to shutdown
credential service because BIOS always get executed prior to OS, right?

Igor: Yes, my point is that we should not shutdown credential service
from BIOS. Even if OS sends that IPMI command, new account will be
created and BIOS credentials will not be compromised.

Should it be configured with some PCD? Maybe user may select in
Setup
what method should be used? Or it could be build time configuration?

I have below assumption while I implemented the library. I admit this
is not always true.

No Auth: I think this is rare case for Redfish service which gives
anonymous privilege to change BIOS settings.
Basic Auth: this is the authentication method which uses username and
password to build base64 encoded string.
Session Auth: I assume that client must have a session token first and
then use this authentication method. Can we use username and password
to generate session token on our own? If my memory serves me
correctly, client has to do a login with username and password first
and then client can receive session token from server.

Igor: BIOS will use the credentials to create session. It should send
POST request to the session URI with user name and password to create session.
If a session created successfully then on response BMC returns header
"X- Auth-Token" which then used for the subsequential calls.

If we really like to know what authentication method that Redfish
service used, we can issue a HTTP query to "/redfish/v1/Systems" with "No Auth".
Then we can know what authentication method is required by reading the
"WWW-Authenticate " filed in returned HTTP header.

Igor: As my understanding, even if you include authentication header
(Base64 encoded) in the request to BMC and BMC has NoAuth
configuration, then that authentication header would be just ignored by BMC.

Thanks,
Nickle

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Igor
Kulchytskyy via groups.io
Sent: Wednesday, October 26, 2022 11:26 PM
To: Nickle Wang <nicklew@...>; devel@edk2.groups.io;
abner.chang@...
Cc: Nick Ramirez <nramirez@...>
Subject: Re: [edk2-devel] [PATCH] RedfishPkg/RedfishPlatformCredentialLib:
IPMI implementation

External email: Use caution opening links or attachments


Hi Nickle,
I would like to discuss that DisableBootstrapControl flag and how it
is used in our implementation.
According to Redfish HI specification we can use this flag to disable
credential bootstrapping control.
It can be disabled permanently or till next reboot of the host or
service. That depend on the EnableAfterReset setting on BMC side:
CredentialBootstrapping (v1.3+)
{ object The credential bootstrapping settings for this interface.
EnableAfterReset (v1.3+) Boolean read-write (null) An
indication of whether credential bootstrapping is enabled after a reset for this interface.
Enabled (v1.3+) Boolean read-write (null) An indication of
whether credential bootstrapping is enabled for this interface.
RoleId (v1.3+) string read-write The role used for the
bootstrap account created for this interface.
}
So, if EnableAfterReset set to false, that means BMC will response
with 0x80 error and will not return any credentials after reboot. And
BIOS BMC communication will fail.
Another concern with disabling credential bootstrapping control is
that we do it on Exit Boot event before passing a control to OS.
But OS may also need to communicate to BMC through Redfish Host
Interface to post some information. And it will be blocked by our IPMI call.
We create that SMBIOS Type 42 table with Redfish Host Interface
settings which can be used by OS to communicate with BMC. But without
the credentials it will not be possible.

Another question is AuthMethod parameter you initialize in this library:
*AuthMethod = AuthMethodHttpBasic;
According to Redfish HI specification 3 methods may be used - No Auth,
Basic Auth and Session Auth.
Basic Auth and Session Auth methods are required the credentials to be
used by BIOS. And both of them should be supported by BMC.
And your high level function RedfishCreateLibredfishService also
supports of creation Basic or Session Auth service.
I'm not sure why low level library which is created to get credentials
from BMC should decide what Authentication method should be used?
Should it be configured with some PCD? Maybe user may select in Setup
what method should be used? Or it could be build time configuration?

Thank you,
Igor

-----Original Message-----
From: Nickle Wang <nicklew@...>
Sent: Tuesday, October 25, 2022 4:24 AM
To: devel@edk2.groups.io; abner.chang@...
Cc: Nick Ramirez <nramirez@...>; Igor Kulchytskyy
<igork@...>
Subject: [EXTERNAL] RE: [edk2-devel] [PATCH]
RedfishPkg/RedfishPlatformCredentialLib: IPMI implementation


**CAUTION: The e-mail below is from an external source. Please
exercise caution before opening attachments, clicking links, or
following guidance.**

Thanks for your review comments, Abner! I will update new version
patch later. The CI build error will be handled together.

please add Igor as reviewer too
Sure!


+ *UserId = AllocateZeroPool (sizeof (CHAR8) * USERNAME_MAX_SIZE);
+ if
[Chang, Abner]
Allocation memory with the size (USERNAME_MAX_LENGTH + 1) for both
BootUsername and BootstrapPassword? Because the maximum number of
characters defined in the spec is USERNAME_MAX_LENGTH for the
user/password.

Yes, the additional one byte is for NULL terminator.
USERNAME_MAX_LENGTH is defined as 16 and follow host interface
specification.

Regards,
Nickle

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Chang,
Abner via groups.io
Sent: Saturday, October 22, 2022 3:01 PM
To: Nickle Wang <nicklew@...>; devel@edk2.groups.io
Cc: Nick Ramirez <nramirez@...>; Igor Kulchytskyy
<igork@...>
Subject: Re: [edk2-devel] [PATCH] RedfishPkg/RedfishPlatformCredentialLib:
IPMI implementation

External email: Use caution opening links or attachments


[AMD Official Use Only - General]

Hi Nickle, please add Igor as reviewer too. My comments is in below,

-----Original Message-----
From: Nickle Wang <nicklew@...>
Sent: Thursday, October 20, 2022 10:55 AM
To: devel@edk2.groups.io
Cc: Chang, Abner <Abner.Chang@...>; Nick Ramirez
<nramirez@...>
Subject: [PATCH] RedfishPkg/RedfishPlatformCredentialLib: IPMI
implementation

Caution: This message originated from an External Source. Use proper
caution when opening attachments, clicking links, or responding.


This library follows Redfish Host Interface specification and use
IPMI command to get bootstrap account credential(NetFn 2Ch, Command
02h)
from BMC.
RedfishHostInterfaceDxe will use this credential for the following
communication between BIOS and BMC.

Cc: Abner Chang <abner.chang@...>
Cc: Nick Ramirez <nramirez@...>
Signed-off-by: Nickle Wang <nicklew@...>
---
.../RedfishPlatformCredentialLib.c | 273 ++++++++++++++++++
.../RedfishPlatformCredentialLib.h | 75 +++++
.../RedfishPlatformCredentialLib.inf | 37 +++
[Chang, Abner]
Could we name this library RedfishPlatformCredentialIpmi so the naming
style is consistent with RedfishPlatformCredentialNull?

3 files changed, 385 insertions(+)
create mode 100644
RedfishPkg/Library/RedfishPlatformCredentialLib/RedfishPlatformCredent
ial
Lib.
c
create mode 100644
RedfishPkg/Library/RedfishPlatformCredentialLib/RedfishPlatformCredent
ial
Lib.
h
create mode 100644
RedfishPkg/Library/RedfishPlatformCredentialLib/RedfishPlatformCrede
nt
ialLib.i
nf

diff --git
a/RedfishPkg/Library/RedfishPlatformCredentialLib/RedfishPlatformCre
de
ntialLi
b.c
b/RedfishPkg/Library/RedfishPlatformCredentialLib/RedfishPlatformCre
de
ntialLi
b.c
new file mode 100644
index 0000000000..23a15ab1fa
--- /dev/null
+++ b/RedfishPkg/Library/RedfishPlatformCredentialLib/RedfishPlatfor
+++ mC
+++ re
+++ dentialLib.c
@@ -0,0 +1,273 @@
+/** @file
+*
+* Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights
reserved.
+*
+* SPDX-License-Identifier: BSD-2-Clause-Patent
[Chang, Abner]
We can have "@par Revision Reference:" in the file header to point
out the spec.
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fnam1
2.safelinks.protection.outlook.com%2F%3Furl%3Dhttps%253A%252F%252Fnam1
&amp;data=05%7C01%7Cnicklew%40nvidia.com%7C90696ea8811e49e371a708dab8e
be2d8%7C43083d15727340c1b7db39efd9ccc17a%7C0%7C0%7C638025620543993279%
7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik
1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&amp;sdata=CyvRgMZREOk5Yf0hU3CmH%2
B08ktxMYw%2Bixr4UVywfrAQ%3D&amp;reserved=0
1.safelinks.protection.outlook.com%2F%3Furl%3Dhttps%253A%252F%252Fww&a
mp;data=05%7C01%7Cigork%40ami.com%7C2b5b562c02c04c90d51208dab8b8c0fd%7
C27e97857e15f486cb58e86c2b3040f93%7C1%7C0%7C638025400915295621%7CUnkno
wn%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiL
CJXVCI6Mn0%3D%7C3000%7C%7C%7C&amp;sdata=Uy%2B3HS336N3rgNSESPcyOPGX3eOR
48hekdz08nLtJU4%3D&amp;reserved=0
w.dmtf.org%2Fsites%2Fdefault%2Ffiles%2Fstandards%2Fdocuments%2FDSP
0270_1.3.0.pdf&amp;data=05%7C01%7Cabner.chang%40amd.com%7C074aa
e162fba49409af408dab8297c03%7C3dd8961fe4884e608e11a82d994e183d%7C
0%7C0%7C638024786060127888%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiM
C4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000
%7C%7C%7C&amp;sdata=yY6hhKjQfVqmNuufbeDNk%2B2FKrebHyIAyS9Ya4
szE3Y%3D&amp;reserved=0

+*
+**/
+
+#include "RedfishPlatformCredentialLib.h"
+
+//
+// Global flag of controlling credential service // BOOLEAN
+mRedfishServiceStopped = FALSE;
+
+/**
+ Notify the Redfish service provide to stop provide configuration
+service to this
platform.
+
+ This function should be called when the platfrom is about to
+ leave the safe
environment.
+ It will notify the Redfish service provider to abort all logined
+ session, and prohibit further login with original auth info.
+ GetAuthInfo() will return EFI_UNSUPPORTED once this function is
returned.
+
+ @param[in] This Pointer to
EDKII_REDFISH_CREDENTIAL_PROTOCOL instance.
+ @param[in] ServiceStopType Reason of stopping Redfish service.
+
+ @retval EFI_SUCCESS Service has been stoped successfully.
+ @retval EFI_INVALID_PARAMETER This is NULL.
+ @retval Others Some error happened.
+
+**/
+EFI_STATUS
+EFIAPI
+LibStopRedfishService (
+ IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This,
+ IN EDKII_REDFISH_CREDENTIAL_STOP_SERVICE_TYPE
ServiceStopType
+ )
+{
+ EFI_STATUS Status;
+
+ if ((ServiceStopType <= ServiceStopTypeNone) || (ServiceStopType
+ >=
ServiceStopTypeMax)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Raise flag first
+ //
+ mRedfishServiceStopped = TRUE;
+
+ //
+ // Notify BMC to disable credential bootstrapping support.
+ //
+ Status = GetBootstrapAccountCredentials (TRUE, NULL, NULL); if
+ (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: fail to disable bootstrap credential:
+ %r\n",
__FUNCTION__, Status));
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Notification of Exit Boot Service.
+
+ @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL.
+**/
+VOID
+EFIAPI
+LibCredentialExitBootServicesNotify (
+ IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This
+ )
+{
+ //
+ // Stop the credential support when system is about to enter OS.
+ //
+ LibStopRedfishService (This, ServiceStopTypeExitBootService); }
+
+/**
+ Notification of End of DXe.
+
+ @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL.
+**/
+VOID
+EFIAPI
+LibCredentialEndOfDxeNotify (
+ IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This
+ )
+{
+ //
+ // Do nothing now.
+ // We can stop credential support when system reach end-of-dxe
+for security
reason.
+ //
+}
+
+/**
+ Function to retrieve temporary use credentials for the UEFI
+redfish client
[Chang, Abner]
We miss the functionality to disable bootstrap credential service in
the function description.

+
+ @param[in] DisableBootstrapControl
+ TRUE - Tell the BMC to disable the bootstrap credential
+ service to ensure no one else gains credentials
+ FALSE Allow the bootstrap
+ credential service to continue @param[out] BootstrapUsername
+ A pointer to a UTF-8 encoded
+ string for the credential
username
+ When DisableBootstrapControl
+ is TRUE, this pointer can be NULL
+
+ @param[out] BootstrapPassword
+ A pointer to a UTF-8 encoded
+ string for the credential
password
+ When DisableBootstrapControl
+ is TRUE, this pointer can be NULL
+
+ @retval EFI_SUCCESS Credentials were successfully fetched and
returned
+ @retval EFI_INVALID_PARAMETER BootstrapUsername or
BootstrapPassword is NULL when DisableBootstrapControl
+ is set to FALSE
+ @retval EFI_DEVICE_ERROR An IPMI failure occurred
[Chang, Abner]
The return status should also include the status of disabling
bootstrap credential.


+**/
+EFI_STATUS
+GetBootstrapAccountCredentials (
+ IN BOOLEAN DisableBootstrapControl,
+ IN OUT CHAR8 *BootstrapUsername, OPTIONAL
+ IN OUT CHAR8 *BootstrapPassword OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ IPMI_BOOTSTRAP_CREDENTIALS_COMMAND_DATA CommandData;
+ IPMI_BOOTSTRAP_CREDENTIALS_RESULT_RESPONSE ResponseData;
+ UINT32 ResponseSize;
+
+ if (!PcdGetBool (PcdIpmiFeatureEnable)) {
+ DEBUG ((DEBUG_ERROR, "%a: IPMI is not enabled! Unable to fetch
+ Redfish
credentials\n", __FUNCTION__));
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // NULL buffer check
+ //
+ if (!DisableBootstrapControl && ((BootstrapUsername == NULL) ||
(BootstrapPassword == NULL))) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DEBUG ((DEBUG_VERBOSE, "%a: Disable bootstrap control: 0x%x\n",
+ __FUNCTION__, DisableBootstrapControl));
+
+ //
+ // IPMI callout to NetFn 2C, command 02
+ // Request data:
+ // Byte 1: REDFISH_IPMI_GROUP_EXTENSION
+ // Byte 2: DisableBootstrapControl
+ //
+ CommandData.GroupExtensionId =
REDFISH_IPMI_GROUP_EXTENSION;
+ CommandData.DisableBootstrapControl = (DisableBootstrapControl ?
+ REDFISH_IPMI_BOOTSTRAP_CREDENTIAL_DISABLE :
+ REDFISH_IPMI_BOOTSTRAP_CREDENTIAL_ENABLE);
+
+ ResponseSize = sizeof (ResponseData);
+
+ //
+ // Response data:
+ // Byte 1 : Completion code
+ // Byte 2 : REDFISH_IPMI_GROUP_EXTENSION
+ // Byte 3-18 : Username
+ // Byte 19-34: Password
+ //
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_GROUP_EXT,
+ REDFISH_IPMI_GET_BOOTSTRAP_CREDENTIALS_CMD,
+ (UINT8 *)&CommandData,
+ sizeof (CommandData),
+ (UINT8 *)&ResponseData,
+ &ResponseSize
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: IPMI transaction failure.
+ Returning\n",
__FUNCTION__));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ } else {
+ if (ResponseData.CompletionCode != IPMI_COMP_CODE_NORMAL) {
+ if (ResponseData.CompletionCode ==
REDFISH_IPMI_COMP_CODE_BOOTSTRAP_CREDENTIAL_DISABLED) {
+ DEBUG ((DEBUG_ERROR, "%a: bootstrap credential support was
disabled\n", __FUNCTION__));
+ return EFI_ACCESS_DENIED;
+ }
+
+ DEBUG ((DEBUG_ERROR, "%a: Completion code = 0x%x.
+ Returning\n",
__FUNCTION__, ResponseData.CompletionCode));
+ return EFI_PROTOCOL_ERROR;
+ } else if (ResponseData.GroupExtensionId !=
REDFISH_IPMI_GROUP_EXTENSION) {
+ DEBUG ((DEBUG_ERROR, "%a: Group Extension Response = 0x%x.
Returning\n", __FUNCTION__, ResponseData.GroupExtensionId));
+ return EFI_DEVICE_ERROR;
+ } else {
+ if (BootstrapUsername != NULL) {
+ CopyMem (BootstrapUsername, ResponseData.Username,
USERNAME_MAX_LENGTH);
+ //
+ // Manually append null-terminator in case 16 characters
+ username
returned.
+ //
+ BootstrapUsername[USERNAME_MAX_LENGTH] = '\0';
+ }
+
+ if (BootstrapPassword != NULL) {
+ CopyMem (BootstrapPassword, ResponseData.Password,
PASSWORD_MAX_LENGTH);
+ //
+ // Manually append null-terminator in case 16 characters
+ password
returned.
+ //
+ BootstrapPassword[PASSWORD_MAX_LENGTH] = '\0';
+ }
+ }
+ }
+
+ return Status;
+}
+
+/**
+ Retrieve platform's Redfish authentication information.
+
+ This functions returns the Redfish authentication method together
+ with the user Id and password.
+ - For AuthMethodNone, the UserId and Password could be used for
+ HTTP
header authentication
+ as defined by RFC7235.
+ - For AuthMethodRedfishSession, the UserId and Password could be
+ used for
Redfish
+ session login as defined by Redfish API specification (DSP0266).
+
+ Callers are responsible for and freeing the returned string storage.
+
+ @param[in] This Pointer to
EDKII_REDFISH_CREDENTIAL_PROTOCOL instance.
+ @param[out] AuthMethod Type of Redfish authentication method.
+ @param[out] UserId The pointer to store the returned UserId
string.
+ @param[out] Password The pointer to store the returned
Password
string.
+
+ @retval EFI_SUCCESS Get the authentication information
successfully.
+ @retval EFI_ACCESS_DENIED SecureBoot is disabled after EndOfDxe.
+ @retval EFI_INVALID_PARAMETER This or AuthMethod or UserId or
Password is NULL.
+ @retval EFI_OUT_OF_RESOURCES There are not enough memory
resources.
+ @retval EFI_UNSUPPORTED Unsupported authentication method is
found.
+
+**/
+EFI_STATUS
+EFIAPI
+LibCredentialGetAuthInfo (
+ IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This,
+ OUT EDKII_REDFISH_AUTH_METHOD *AuthMethod,
+ OUT CHAR8 **UserId,
+ OUT CHAR8 **Password
+ )
+{
+ EFI_STATUS Status;
+
+ if ((AuthMethod == NULL) || (UserId == NULL) || (Password == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *UserId = NULL;
+ *Password = NULL;
+
+ if (mRedfishServiceStopped) {
+ DEBUG ((DEBUG_ERROR, "%a: credential service is stopped due to
+ security
reason\n", __FUNCTION__));
+ return EFI_ACCESS_DENIED;
+ }
+
+ *AuthMethod = AuthMethodHttpBasic;
+
+ *UserId = AllocateZeroPool (sizeof (CHAR8) * USERNAME_MAX_SIZE);
+ if
[Chang, Abner]
Allocation memory with the size (USERNAME_MAX_LENGTH + 1) for both
BootUsername and BootstrapPassword? Because the maximum number of
characters defined in the spec is USERNAME_MAX_LENGTH for the
user/password.


+ (*UserId == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ *Password = AllocateZeroPool (sizeof (CHAR8) *
+ PASSWORD_MAX_SIZE); if (*Password == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = GetBootstrapAccountCredentials (FALSE, *UserId,
+ *Password); if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: fail to get bootstrap credential:
+ %r\n",
__FUNCTION__, Status));
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
diff --git
a/RedfishPkg/Library/RedfishPlatformCredentialLib/RedfishPlatformCre
de
ntialLi
b.h
b/RedfishPkg/Library/RedfishPlatformCredentialLib/RedfishPlatformCre
de
ntialLi
b.h
new file mode 100644
index 0000000000..5b448e01be
--- /dev/null
+++ b/RedfishPkg/Library/RedfishPlatformCredentialLib/RedfishPlatfor
+++ mC
+++ re
+++ dentialLib.h
@@ -0,0 +1,75 @@
+/** @file
+*
+* Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights
reserved.
+*
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+#include <Uefi.h>
+#include <IndustryStandard/Ipmi.h>
+#include <Protocol/EdkIIRedfishCredential.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IpmiBaseLib.h>
+#include <Library/MemoryAllocationLib.h> #include
+<Library/RedfishCredentialLib.h>
+
+#define REDFISH_IPMI_GROUP_EXTENSION 0x52
+#define REDFISH_IPMI_GET_BOOTSTRAP_CREDENTIALS_CMD 0x02
+#define REDFISH_IPMI_BOOTSTRAP_CREDENTIAL_ENABLE 0xA5
+#define REDFISH_IPMI_BOOTSTRAP_CREDENTIAL_DISABLE 0x00
+#define
REDFISH_IPMI_COMP_CODE_BOOTSTRAP_CREDENTIAL_DISABLED
0x80
+
+//
+// Per Redfish Host Interface Specification 1.3, The maximum lenght
+of // username and password is 16 characters long.
+//
+#define USERNAME_MAX_LENGTH 16
+#define PASSWORD_MAX_LENGTH 16
+#define USERNAME_MAX_SIZE (USERNAME_MAX_LENGTH + 1) //
NULL
terminator
+#define PASSWORD_MAX_SIZE (PASSWORD_MAX_LENGTH + 1) //
NULL
terminator
+
+#pragma pack(1)
+///
+/// The definition of IPMI command to get bootstrap account
+credentials /// typedef struct {
+ UINT8 GroupExtensionId;
+ UINT8 DisableBootstrapControl;
+} IPMI_BOOTSTRAP_CREDENTIALS_COMMAND_DATA;
+
+///
+/// The response data of getting bootstrap credential /// typedef
+struct {
+ UINT8 CompletionCode;
+ UINT8 GroupExtensionId;
+ CHAR8 Username[USERNAME_MAX_LENGTH];
+ CHAR8 Password[PASSWORD_MAX_LENGTH];
+} IPMI_BOOTSTRAP_CREDENTIALS_RESULT_RESPONSE;
+
+#pragma pack()
+
+/**
+ Function to retrieve temporary use credentials for the UEFI
+redfish client
[Chang, Abner]
We miss the functionality to disable bootstrap credential service in
the function description.

+
+ @param[in] DisableBootstrapControl
+ TRUE - Tell the BMC to disable the bootstrap credential
+ service to ensure no one else gains credentials
+ FALSE Allow the bootstrap
+ credential service to continue @param[out] BootstrapUsername
+ A pointer to a UTF-8 encoded
+ string for the credential username
+
+ @param[out] BootstrapPassword
+ A pointer to a UTF-8 encoded
+ string for the credential password
+
+ @retval EFI_SUCCESS Credentials were successfully fetched and
returned
[Chang, Abner]
Or the bootstrap credential service is disabled successfully, right?

+ @retval EFI_DEVICE_ERROR An IPMI failure occurred
+**/
+EFI_STATUS
+GetBootstrapAccountCredentials (
+ IN BOOLEAN DisableBootstrapControl,
+ IN OUT CHAR8 *BootstrapUsername,
+ IN OUT CHAR8 *BootstrapPassword
+ );
diff --git
a/RedfishPkg/Library/RedfishPlatformCredentialLib/RedfishPlatformCre
de
ntialLi
b.inf
b/RedfishPkg/Library/RedfishPlatformCredentialLib/RedfishPlatformCre
de
ntialLi
b.inf
new file mode 100644
index 0000000000..a990d28363
--- /dev/null
+++ b/RedfishPkg/Library/RedfishPlatformCredentialLib/RedfishPlatfor
+++ mC
+++ re
+++ dentialLib.inf
@@ -0,0 +1,37 @@
+## @file
+#
+# Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights
reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+[Defines]
+ INF_VERSION = 0x0001000b
+ BASE_NAME = RedfishPlatformCredentialLib
+ FILE_GUID = 9C45D622-4C66-417F-814C-F76246D97233
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = RedfishPlatformCredentialLib
+
+[Sources]
+ RedfishPlatformCredentialLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ RedfishPkg/RedfishPkg.dec
+ IpmiFeaturePkg/IpmiFeaturePkg.dec
[Chang, Abner]
Could you please add a comment to the reference of IpmiFeaturePkg? We
have to give customers a notice that the dependence of "edk2-
platforms/Features/Intel/OutOfBandManagement/". They have to add the
path to PACKAGES_PATH. You also have to skip this dependence in the
RedfishPkg.yaml to avoid the CI error.

Another thing is I propose to move out IpmiFeaturePkg from edk2-
platforms/Features/Intel/OutOfBandManagement to edk2-
platforms/Features/ManageabilityPkg that also provides the
implementation of PLDM/MCTP/IPMI/KCS. I had an initial talk with
IpmiFeaturePkg owner and get the positive response on this proposal. I
will kick off the discussion on the dev mailing list. That is to say
this module may need a little bit change later, however that is good
to me having this implementation now.
Thanks
Abner
+
+[LibraryClasses]
+ UefiLib
+ DebugLib
+ IpmiBaseLib
+ MemoryAllocationLib
+ BaseMemoryLib
+
+[Pcd]
+ gIpmiFeaturePkgTokenSpaceGuid.PcdIpmiFeatureEnable
+
+[Depex]
+ TRUE
--
2.17.1




-The information contained in this message may be confidential and
proprietary to American Megatrends (AMI). This communication is
intended to be read only by the individual or entity to whom it is
addressed or by their designee. If the reader of this message is not
the intended recipient, you are on notice that any distribution of
this message, in any form, is strictly prohibited. Please promptly
notify the sender by reply e-mail or by telephone at 770-246-8600, and
then delete or destroy all copies of the transmission.










-The information contained in this message may be confidential and
proprietary to American Megatrends (AMI). This communication is
intended to be read only by the individual or entity to whom it is
addressed or by their designee. If the reader of this message is not
the intended recipient, you are on notice that any distribution of
this message, in any form, is strictly prohibited. Please promptly
notify the sender by reply e-mail or by telephone at 770-246-8600, and
then delete or destroy all copies of the transmission.



-The information contained in this message may be confidential and proprietary to American Megatrends (AMI). This communication is intended to be read only by the individual or entity to whom it is addressed or by their designee. If the reader of this message is not the intended recipient, you are on notice that any distribution of this message, in any form, is strictly prohibited. Please promptly notify the sender by reply e-mail or by telephone at 770-246-8600, and then delete or destroy all copies of the transmission.


Re: [PATCH v2] edk2Platforms-Silicon:Add VAB FIT record types support in FitGen.c

Hv, Pavamana
 

Hi Bob,

I had run the check and ran it again and this is what I get

 

C:\Work\Tianocore\edk2-platforms> c:\python38\python ..\edk2\BaseTools\Scripts\PatchCheck.py .\0001-edk2Platforms-Silicon-Add-VAB-FIT-record-types-suppo.patch

Checking patch file: .\0001-edk2Platforms-Silicon-Add-VAB-FIT-record-types-suppo.patch

edk2Platforms-Silicon:Add VAB FIT record types support in FitGen.c

The commit message format passed all checks.

The code passed all checks.

 

I am not sure what you are seeing. Can you please paste your output? Am I missing something?

 

Regards,

Pavamana

 

From: Feng, Bob C <bob.c.feng@...>
Sent: Thursday, October 27, 2022 10:33 PM
To: devel@edk2.groups.io; Gao, Liming <gaoliming@...>; Holland, Michael <michael.holland@...>; Hv, Pavamana <pavamana.hv@...>; Chaganty, Rangasai V <rangasai.v.chaganty@...>; Lohr, Paul A <paul.a.lohr@...>
Subject: RE: [edk2-devel] [PATCH v2] edk2Platforms-Silicon:Add VAB FIT record types support in FitGen.c

 

Hi Pavamana,

 

I found there are few patch format issues.  Please use edk2\BaseTools\Scripts\PatchCheck.py to check the patch and fix them. After that, I’ll merge it.

 

Thanks,

Bob

 

From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of gaoliming via groups.io
Sent: Friday, October 28, 2022 9:11 AM
To: Holland, Michael <michael.holland@...>; Hv, Pavamana <pavamana.hv@...>; devel@edk2.groups.io; Chaganty, Rangasai V <rangasai.v.chaganty@...>; Lohr, Paul A <paul.a.lohr@...>; Feng, Bob C <bob.c.feng@...>
Subject: 回复: [edk2-devel] [PATCH v2] edk2Platforms-Silicon:Add VAB FIT record types support in FitGen.c

 

Michael:

 Thanks for your sharing.

 

Pavamana:

 FIT spec 1.4 has been published. So, this change can be merged now.

 

Thanks

Liming

发件人: Holland, Michael <michael.holland@...>
发送时间: 20221028 1:41
收件人: Gao, Liming <gaoliming@...>; Hv, Pavamana <pavamana.hv@...>; devel@edk2.groups.io; Chaganty, Rangasai V <rangasai.v.chaganty@...>; Lohr, Paul A <paul.a.lohr@...>; Feng, Bob C <bob.c.feng@...>
主题: RE: [edk2-devel] [PATCH v2] edk2Platforms-Silicon:Add VAB FIT record types support in FitGen.c

 

Hi Liming,

 

Please see published FIT spec 1.4:  https://edc.intel.com/content/www/us/en/design/products-and-solutions/software-and-services/firmware-and-bios/firmware-interface-table/

 

Thanks,

Michael

 

From: gaoliming <gaoliming@...>
Sent: Wednesday, October 26, 2022 07:59 PM
To: Hv, Pavamana <pavamana.hv@...>; Holland, Michael <michael.holland@...>; devel@edk2.groups.io; Chaganty, Rangasai V <rangasai.v.chaganty@...>; Lohr, Paul A <paul.a.lohr@...>; Feng, Bob C <bob.c.feng@...>
Subject: 回复: [edk2-devel] [PATCH v2] edk2Platforms-Silicon:Add VAB FIT record types support in FitGen.c

 

Pavamana:

 The change should be merged after new FIT spec is published, because FitGen tool follows the public FIT spec.

 

Thanks

Liming

发件人: Hv, Pavamana <pavamana.hv@...>
发送时间: 20221026 23:13
收件人: Holland, Michael <michael.holland@...>; Gao, Liming <gaoliming@...>; devel@edk2.groups.io; Chaganty, Rangasai V <rangasai.v.chaganty@...>; Lohr, Paul A <paul.a.lohr@...>; Feng, Bob C <bob.c.feng@...>
主题: RE: [edk2-devel] [PATCH v2] edk2Platforms-Silicon:Add VAB FIT record types support in FitGen.c

 

Thanks for the review, Liming.

@Feng, Bob C,

What is the next step to merge the change?

Let me know if anything is needed from me.

Thanks for your help again.

Regards,

Pavamana

 

 

From: Holland, Michael <michael.holland@...>
Sent: Tuesday, October 25, 2022 8:36 PM
To: Gao, Liming <gaoliming@...>; devel@edk2.groups.io; Hv, Pavamana <pavamana.hv@...>; Chaganty, Rangasai V <rangasai.v.chaganty@...>; Lohr, Paul A <paul.a.lohr@...>
Cc: Feng, Bob C <bob.c.feng@...>
Subject: RE: [edk2-devel] [PATCH v2] edk2Platforms-Silicon:Add VAB FIT record types support in FitGen.c

 

Hi Liming,

 

The spec is in process of being published.

 

@Chaganty, Rangasai V @Lohr, Paul A

 

Any update on FIT spec being published?

 

Thanks,

Michael

 

From: gaoliming <gaoliming@...>
Sent: Tuesday, October 25, 2022 09:18 PM
To: devel@edk2.groups.io; Hv, Pavamana <pavamana.hv@...>
Cc: Feng, Bob C <bob.c.feng@...>; Holland, Michael <michael.holland@...>
Subject: 回复: [edk2-devel] [PATCH v2] edk2Platforms-Silicon:Add VAB FIT record types support in FitGen.c

 

Pavamana:

 The code change looks good. Now,  is FIT spec 1.4 public to be downloaded?

 

Thanks

Liming

发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Hv, Pavamana
发送时间: 20221026 5:50
收件人: devel@edk2.groups.io; Gao, Liming <gaoliming@...>
抄送: Feng, Bob C <bob.c.feng@...>; Holland, Michael <michael.holland@...>
主题: Re: [edk2-devel] [PATCH v2] edk2Platforms-Silicon:Add VAB FIT record types support in FitGen.c
重要性:

 

Hi Liming,

Any update on this? Please treat this with urgency as we have a release coming up and needs this change.

 

-Pavamana

 

From: Hv, Pavamana
Sent: Monday, October 24, 2022 10:05 AM
To: devel@edk2.groups.io; Gao, Liming <gaoliming@...>
Subject: RE: [PATCH v2] edk2Platforms-Silicon:Add VAB FIT record types support in FitGen.c

 

@Gao, Liming,

Can you please review the patch and let me know if this can be merged?

Thanks in advance for your help.

Regards,

Pavamana

 

-----Original Message-----
From: Hv, Pavamana <pavamana.hv@...>
Sent: Wednesday, October 19, 2022 8:57 PM
To: devel@edk2.groups.io
Cc: Hv, Pavamana <pavamana.hv@...>
Subject: [PATCH v2] edk2Platforms-Silicon:Add VAB FIT record types support in FitGen.c

 

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4086

 

This commit adds support for new FIT record type for Vendor Authorized Boot (VAB) security technology(FIT spec revision 1.4).

VAB defines 3 new following types

Vendor Authorized Boot Provisioning Table (Type 0x1A) Vendor Authorized Boot Image Manifest (Type 0x1B) Vendor Authorized Boot Key Manifest (Type 0x1C) The code has been updated to align these binaries on 64 byte boundary and not to overlap with other regions, similar to Key manifest, Boot Policy manifest and other optional types.

 

Also added macros to define FIT spec Major and Minor version numbers and print the same instead of hardcoded string.

 

Signed-off-by: Pavamana Holavanahalli <pavamana.hv@...>

---

Silicon/Intel/Tools/FitGen/FitGen.c | 61 +++++++++++++++++++----------  Silicon/Intel/Tools/FitGen/FitGen.h |  5 ++-

2 files changed, 44 insertions(+), 22 deletions(-)

 

diff --git a/Silicon/Intel/Tools/FitGen/FitGen.c b/Silicon/Intel/Tools/FitGen/FitGen.c

index 21dfcf1ebb..87123f9922 100644

--- a/Silicon/Intel/Tools/FitGen/FitGen.c

+++ b/Silicon/Intel/Tools/FitGen/FitGen.c

@@ -234,20 +234,24 @@ typedef struct {

#define FLASH_TO_MEMORY(Address, FvBuffer, FvSize)  \                  (VOID *)(UINTN)((UINTN)(FvBuffer) + (UINTN)(FvSize) - (TOP_FLASH_ADDRESS - (UINTN)(Address))) -#define FIT_TABLE_TYPE_HEADER                 0-#define FIT_TABLE_TYPE_MICROCODE              1-#define FIT_TABLE_TYPE_STARTUP_ACM            2-#define FIT_TABLE_TYPE_DIAGNST_ACM            3-#define FIT_TABLE_TYPE_BIOS_MODULE            7-#define FIT_TABLE_TYPE_TPM_POLICY             8-#define FIT_TABLE_TYPE_BIOS_POLICY            9-#define FIT_TABLE_TYPE_TXT_POLICY             10-#define FIT_TABLE_TYPE_KEY_MANIFEST           11-#define FIT_TABLE_TYPE_BOOT_POLICY_MANIFEST   12-#define FIT_TABLE_TYPE_BIOS_DATA_AREA         13-#define FIT_TABLE_TYPE_CSE_SECURE_BOOT        16-#define FIT_TABLE_SUBTYPE_FIT_PATCH_MANIFEST  12-#define FIT_TABLE_SUBTYPE_ACM_MANIFEST        13+#define FIT_TABLE_TYPE_HEADER                      0+#define FIT_TABLE_TYPE_MICROCODE                   1+#define FIT_TABLE_TYPE_STARTUP_ACM                 2+#define FIT_TABLE_TYPE_DIAGNST_ACM                 3+#define FIT_TABLE_TYPE_BIOS_MODULE                 7+#define FIT_TABLE_TYPE_TPM_POLICY                  8+#define FIT_TABLE_TYPE_BIOS_POLICY                 9+#define FIT_TABLE_TYPE_TXT_POLICY                  10+#define FIT_TABLE_TYPE_KEY_MANIFEST                11+#define FIT_TABLE_TYPE_BOOT_POLICY_MANIFEST        12+#define FIT_TABLE_TYPE_BIOS_DATA_AREA              13+#define FIT_TABLE_TYPE_CSE_SECURE_BOOT             16+#define FIT_TABLE_SUBTYPE_FIT_PATCH_MANIFEST       12+#define FIT_TABLE_SUBTYPE_ACM_MANIFEST             13+#define FIT_TABLE_TYPE_VAB_PROVISION_TABLE         26+#define FIT_TABLE_TYPE_VAB_BOOT_IMAGE_MANIFEST     27+#define FIT_TABLE_TYPE_VAB_BOOT_KEY_MANIFEST       28+  // // With OptionalModule Address isn't known until free space has been@@ -322,8 +326,10 @@ Returns:

--*/ {   printf (-    "%s - Tiano IA32/X64 FIT table generation Utility for FIT spec revision 1.2."" Version %i.%i\n\n",+    "%s - Tiano IA32/X64 FIT table generation Utility for FIT spec revision %i.%i."" Version %i.%i\n\n",     UTILITY_NAME,+    FIT_SPEC_VERSION_MAJOR,+    FIT_SPEC_VERSION_MINOR,     UTILITY_MAJOR_VERSION,     UTILITY_MINOR_VERSION     );@@ -1956,7 +1962,10 @@ Returns:

         (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_KEY_MANIFEST) ||         (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_BOOT_POLICY_MANIFEST) ||         (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_BIOS_DATA_AREA) ||-        (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_CSE_SECURE_BOOT)) {+        (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_CSE_SECURE_BOOT) ||+        (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_VAB_PROVISION_TABLE) ||+        (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_VAB_BOOT_IMAGE_MANIFEST) ||+        (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_VAB_BOOT_KEY_MANIFEST)) {       // NOTE: It might be virtual address now. Just put a place holder.       FitEntryNumber ++;     }@@ -2154,8 +2163,11 @@ Returns:

           (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_KEY_MANIFEST) ||           (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_BOOT_POLICY_MANIFEST) ||           (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_BIOS_DATA_AREA) ||-          (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_CSE_SECURE_BOOT)) {-        // Let it 64 byte align+          (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_CSE_SECURE_BOOT) ||+          (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_VAB_PROVISION_TABLE) ||+          (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_VAB_BOOT_IMAGE_MANIFEST) ||+          (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_VAB_BOOT_KEY_MANIFEST)) {+          // Let it 64 byte align         AlignedSize += BIOS_MODULE_ALIGNMENT;         AlignedSize &= ~BIOS_MODULE_ALIGNMENT;       }@@ -2166,8 +2178,11 @@ Returns:

           (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_KEY_MANIFEST) ||           (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_BOOT_POLICY_MANIFEST) ||           (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_BIOS_DATA_AREA) ||-          (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_CSE_SECURE_BOOT)) {-        // Let it 64 byte align+          (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_CSE_SECURE_BOOT) ||+          (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_VAB_PROVISION_TABLE) ||+          (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_VAB_BOOT_IMAGE_MANIFEST) ||+          (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_VAB_BOOT_KEY_MANIFEST)) {+          // Let it 64 byte align         OptionalModuleAddress = (UINT8 *)((UINTN)OptionalModuleAddress & ~BIOS_MODULE_ALIGNMENT);       } @@ -2201,7 +2216,11 @@ Returns:

         (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_KEY_MANIFEST) ||         (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_BOOT_POLICY_MANIFEST) ||         (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_BIOS_DATA_AREA) ||-        (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_CSE_SECURE_BOOT)) {+        (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_CSE_SECURE_BOOT) ||+        (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_VAB_PROVISION_TABLE) ||+        (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_VAB_BOOT_IMAGE_MANIFEST) ||+        (gFitTableContext.OptionalModule[Index].Type == FIT_TABLE_TYPE_VAB_BOOT_KEY_MANIFEST)) {+       CheckOverlap (gFitTableContext.OptionalModule[Index].Address, AlignedSize);     }   }diff --git a/Silicon/Intel/Tools/FitGen/FitGen.h b/Silicon/Intel/Tools/FitGen/FitGen.h

index 80a1423ceb..511ab652ab 100644

--- a/Silicon/Intel/Tools/FitGen/FitGen.h

+++ b/Silicon/Intel/Tools/FitGen/FitGen.h

@@ -31,9 +31,12 @@ SPDX-License-Identifier: BSD-2-Clause-Patent

// Utility version information // #define UTILITY_MAJOR_VERSION 0-#define UTILITY_MINOR_VERSION 66+#define UTILITY_MINOR_VERSION 67 #define UTILITY_DATE          __DATE__ +#define FIT_SPEC_VERSION_MAJOR 1+#define FIT_SPEC_VERSION_MINOR 4+ // // The minimum number of arguments accepted from the command line. //--

2.26.2.windows.1

 


Re: [PATCH] RedfishPkg/RedfishPlatformCredentialLib: IPMI implementation

Igor Kulchytskyy
 

Hi Abner,
Yes, you are right that NVRAM variables were deprecated by DMTF.
But we can use our own boot time NVRAM variable to keep FW credentials. That variable will not be accessible from OS, but since we agreed not to disable bootstrap credentials service on exit boot event, then OS may get its own credentials.
Or we can save the credentials in memory variable. But in this case if we have several instances of the library linked with different modules they will have to send their own IPMI command to get credentials.
So, I think it is better to use our own NVRAM boot time variable.
Thank you,
Igor

-----Original Message-----
From: Chang, Abner <Abner.Chang@...>
Sent: Friday, October 28, 2022 3:48 AM
To: devel@edk2.groups.io; Igor Kulchytskyy <igork@...>; nicklew@...
Cc: Nick Ramirez <nramirez@...>
Subject: [EXTERNAL] RE: [edk2-devel] [PATCH] RedfishPkg/RedfishPlatformCredentialLib: IPMI implementation


**CAUTION: The e-mail below is from an external source. Please exercise caution before opening attachments, clicking links, or following guidance.**

[AMD Official Use Only - General]



-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Igor
Kulchytskyy via groups.io
Sent: Thursday, October 27, 2022 10:42 PM
To: devel@edk2.groups.io; nicklew@...; Chang, Abner
<Abner.Chang@...>
Cc: Nick Ramirez <nramirez@...>
Subject: Re: [edk2-devel] [PATCH] RedfishPkg/RedfishPlatformCredentialLib:
IPMI implementation

Caution: This message originated from an External Source. Use proper
caution when opening attachments, clicking links, or responding.


Hi Nickle,
Pleased, see my comments on your questions below.

Another point I missed in my previous mail.
You have that function in the library to get credentials and it is
used by RedfishCredentialsDxe driver to create the protocol which in
its turn will be used by other Redfish modules.
We do not know how many modules and how many times will call this
function during boot. Right?
And on each call of this function you call IPMI command. That command
will create new Redfish account on BMC side according to Redfish HI specification:

" If the Get Bootstrap Account Credentials command has been issued and
responds with the completion code 00h, a bootstrap account shall be
added to the manager's account collection and enabled. If the Get
Bootstrap Account Credentials command is sent subsequent times and
responds with the completion code 00h, a new account shall be created
based on the newly generated credentials. Any existing bootstrap accounts shall remain active."

As I know BMC may have some restrictions on the number of Redfish
accounts they can support.
And because of that BOS may hit this limit. Which is not good.
On the other hand I'm not sure we need to have different credentials
for different modules? All those modules are part of FW. And all of
them will be associated with the same RoleID (FW role) on BMC side.
So, all of them may use the same credentials.
Could we cash the credentials on first call of that
Yes, this is something we have to avoid. Many accounts will be created while each of Redfish client module requests a credential. FW can save it in EFI variable and delete it at proper timing. Unfortunately the credential delivering via EFI variable section was deprecated, otherwise we can deliver the credential to OS through EFI variable with disabling the bootstrap credential at exit boot service.

Abner

RedfishCredentialGetAuthInfo and then use those cashed credentials on
subsequential calls?
It will also may save a boot time, since there is no need to send IPMI
command.

Thank you,
Igor

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Nickle
Wang via groups.io
Sent: Thursday, October 27, 2022 9:26 AM
To: devel@edk2.groups.io; Igor Kulchytskyy <igork@...>;
abner.chang@...
Cc: Nick Ramirez <nramirez@...>
Subject: [EXTERNAL] Re: [edk2-devel] [PATCH]
RedfishPkg/RedfishPlatformCredentialLib: IPMI implementation


**CAUTION: The e-mail below is from an external source. Please
exercise caution before opening attachments, clicking links, or
following guidance.**

Hi Igor,

Thank you for your help to review my changes.

And it will be blocked by our IPMI call.
I see your point. So, BIOS should never be the person to shutdown
credential service because BIOS always get executed prior to OS, right?

Igor: Yes, my point is that we should not shutdown credential service
from BIOS. Even if OS sends that IPMI command, new account will be
created and BIOS credentials will not be compromised.

Should it be configured with some PCD? Maybe user may select in
Setup
what method should be used? Or it could be build time configuration?

I have below assumption while I implemented the library. I admit this
is not always true.

No Auth: I think this is rare case for Redfish service which gives
anonymous privilege to change BIOS settings.
Basic Auth: this is the authentication method which uses username and
password to build base64 encoded string.
Session Auth: I assume that client must have a session token first and
then use this authentication method. Can we use username and password
to generate session token on our own? If my memory serves me
correctly, client has to do a login with username and password first
and then client can receive session token from server.

Igor: BIOS will use the credentials to create session. It should send
POST request to the session URI with user name and password to create session.
If a session created successfully then on response BMC returns header
"X- Auth-Token" which then used for the subsequential calls.

If we really like to know what authentication method that Redfish
service used, we can issue a HTTP query to "/redfish/v1/Systems" with "No Auth".
Then we can know what authentication method is required by reading the
"WWW-Authenticate " filed in returned HTTP header.

Igor: As my understanding, even if you include authentication header
(Base64 encoded) in the request to BMC and BMC has NoAuth
configuration, then that authentication header would be just ignored by BMC.

Thanks,
Nickle

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Igor
Kulchytskyy via groups.io
Sent: Wednesday, October 26, 2022 11:26 PM
To: Nickle Wang <nicklew@...>; devel@edk2.groups.io;
abner.chang@...
Cc: Nick Ramirez <nramirez@...>
Subject: Re: [edk2-devel] [PATCH] RedfishPkg/RedfishPlatformCredentialLib:
IPMI implementation

External email: Use caution opening links or attachments


Hi Nickle,
I would like to discuss that DisableBootstrapControl flag and how it
is used in our implementation.
According to Redfish HI specification we can use this flag to disable
credential bootstrapping control.
It can be disabled permanently or till next reboot of the host or
service. That depend on the EnableAfterReset setting on BMC side:
CredentialBootstrapping (v1.3+)
{ object The credential bootstrapping settings for this interface.
EnableAfterReset (v1.3+) Boolean read-write (null) An
indication of whether credential bootstrapping is enabled after a reset for this interface.
Enabled (v1.3+) Boolean read-write (null) An indication of
whether credential bootstrapping is enabled for this interface.
RoleId (v1.3+) string read-write The role used for the
bootstrap account created for this interface.
}
So, if EnableAfterReset set to false, that means BMC will response
with 0x80 error and will not return any credentials after reboot. And
BIOS BMC communication will fail.
Another concern with disabling credential bootstrapping control is
that we do it on Exit Boot event before passing a control to OS.
But OS may also need to communicate to BMC through Redfish Host
Interface to post some information. And it will be blocked by our IPMI call.
We create that SMBIOS Type 42 table with Redfish Host Interface
settings which can be used by OS to communicate with BMC. But without
the credentials it will not be possible.

Another question is AuthMethod parameter you initialize in this library:
*AuthMethod = AuthMethodHttpBasic;
According to Redfish HI specification 3 methods may be used - No Auth,
Basic Auth and Session Auth.
Basic Auth and Session Auth methods are required the credentials to be
used by BIOS. And both of them should be supported by BMC.
And your high level function RedfishCreateLibredfishService also
supports of creation Basic or Session Auth service.
I'm not sure why low level library which is created to get credentials
from BMC should decide what Authentication method should be used?
Should it be configured with some PCD? Maybe user may select in Setup
what method should be used? Or it could be build time configuration?

Thank you,
Igor

-----Original Message-----
From: Nickle Wang <nicklew@...>
Sent: Tuesday, October 25, 2022 4:24 AM
To: devel@edk2.groups.io; abner.chang@...
Cc: Nick Ramirez <nramirez@...>; Igor Kulchytskyy
<igork@...>
Subject: [EXTERNAL] RE: [edk2-devel] [PATCH]
RedfishPkg/RedfishPlatformCredentialLib: IPMI implementation


**CAUTION: The e-mail below is from an external source. Please
exercise caution before opening attachments, clicking links, or
following guidance.**

Thanks for your review comments, Abner! I will update new version
patch later. The CI build error will be handled together.

please add Igor as reviewer too
Sure!


+ *UserId = AllocateZeroPool (sizeof (CHAR8) * USERNAME_MAX_SIZE);
+ if
[Chang, Abner]
Allocation memory with the size (USERNAME_MAX_LENGTH + 1) for both
BootUsername and BootstrapPassword? Because the maximum number of
characters defined in the spec is USERNAME_MAX_LENGTH for the
user/password.

Yes, the additional one byte is for NULL terminator.
USERNAME_MAX_LENGTH is defined as 16 and follow host interface
specification.

Regards,
Nickle

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Chang,
Abner via groups.io
Sent: Saturday, October 22, 2022 3:01 PM
To: Nickle Wang <nicklew@...>; devel@edk2.groups.io
Cc: Nick Ramirez <nramirez@...>; Igor Kulchytskyy
<igork@...>
Subject: Re: [edk2-devel] [PATCH] RedfishPkg/RedfishPlatformCredentialLib:
IPMI implementation

External email: Use caution opening links or attachments


[AMD Official Use Only - General]

Hi Nickle, please add Igor as reviewer too. My comments is in below,

-----Original Message-----
From: Nickle Wang <nicklew@...>
Sent: Thursday, October 20, 2022 10:55 AM
To: devel@edk2.groups.io
Cc: Chang, Abner <Abner.Chang@...>; Nick Ramirez
<nramirez@...>
Subject: [PATCH] RedfishPkg/RedfishPlatformCredentialLib: IPMI
implementation

Caution: This message originated from an External Source. Use proper
caution when opening attachments, clicking links, or responding.


This library follows Redfish Host Interface specification and use
IPMI command to get bootstrap account credential(NetFn 2Ch, Command
02h)
from BMC.
RedfishHostInterfaceDxe will use this credential for the following
communication between BIOS and BMC.

Cc: Abner Chang <abner.chang@...>
Cc: Nick Ramirez <nramirez@...>
Signed-off-by: Nickle Wang <nicklew@...>
---
.../RedfishPlatformCredentialLib.c | 273 ++++++++++++++++++
.../RedfishPlatformCredentialLib.h | 75 +++++
.../RedfishPlatformCredentialLib.inf | 37 +++
[Chang, Abner]
Could we name this library RedfishPlatformCredentialIpmi so the naming
style is consistent with RedfishPlatformCredentialNull?

3 files changed, 385 insertions(+)
create mode 100644
RedfishPkg/Library/RedfishPlatformCredentialLib/RedfishPlatformCredent
ial
Lib.
c
create mode 100644
RedfishPkg/Library/RedfishPlatformCredentialLib/RedfishPlatformCredent
ial
Lib.
h
create mode 100644
RedfishPkg/Library/RedfishPlatformCredentialLib/RedfishPlatformCrede
nt
ialLib.i
nf

diff --git
a/RedfishPkg/Library/RedfishPlatformCredentialLib/RedfishPlatformCre
de
ntialLi
b.c
b/RedfishPkg/Library/RedfishPlatformCredentialLib/RedfishPlatformCre
de
ntialLi
b.c
new file mode 100644
index 0000000000..23a15ab1fa
--- /dev/null
+++ b/RedfishPkg/Library/RedfishPlatformCredentialLib/RedfishPlatfor
+++ mC
+++ re
+++ dentialLib.c
@@ -0,0 +1,273 @@
+/** @file
+*
+* Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights
reserved.
+*
+* SPDX-License-Identifier: BSD-2-Clause-Patent
[Chang, Abner]
We can have "@par Revision Reference:" in the file header to point
out the spec.
https://nam12.safelinks.protection.outlook.com/?url=https%3A%2F%2Fnam1
1.safelinks.protection.outlook.com%2F%3Furl%3Dhttps%253A%252F%252Fww&a
mp;data=05%7C01%7Cigork%40ami.com%7C2b5b562c02c04c90d51208dab8b8c0fd%7
C27e97857e15f486cb58e86c2b3040f93%7C1%7C0%7C638025400915295621%7CUnkno
wn%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiL
CJXVCI6Mn0%3D%7C3000%7C%7C%7C&amp;sdata=Uy%2B3HS336N3rgNSESPcyOPGX3eOR
48hekdz08nLtJU4%3D&amp;reserved=0
w.dmtf.org%2Fsites%2Fdefault%2Ffiles%2Fstandards%2Fdocuments%2FDSP
0270_1.3.0.pdf&amp;data=05%7C01%7Cabner.chang%40amd.com%7C074aa
e162fba49409af408dab8297c03%7C3dd8961fe4884e608e11a82d994e183d%7C
0%7C0%7C638024786060127888%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiM
C4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000
%7C%7C%7C&amp;sdata=yY6hhKjQfVqmNuufbeDNk%2B2FKrebHyIAyS9Ya4
szE3Y%3D&amp;reserved=0

+*
+**/
+
+#include "RedfishPlatformCredentialLib.h"
+
+//
+// Global flag of controlling credential service // BOOLEAN
+mRedfishServiceStopped = FALSE;
+
+/**
+ Notify the Redfish service provide to stop provide configuration
+service to this
platform.
+
+ This function should be called when the platfrom is about to
+ leave the safe
environment.
+ It will notify the Redfish service provider to abort all logined
+ session, and prohibit further login with original auth info.
+ GetAuthInfo() will return EFI_UNSUPPORTED once this function is
returned.
+
+ @param[in] This Pointer to
EDKII_REDFISH_CREDENTIAL_PROTOCOL instance.
+ @param[in] ServiceStopType Reason of stopping Redfish service.
+
+ @retval EFI_SUCCESS Service has been stoped successfully.
+ @retval EFI_INVALID_PARAMETER This is NULL.
+ @retval Others Some error happened.
+
+**/
+EFI_STATUS
+EFIAPI
+LibStopRedfishService (
+ IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This,
+ IN EDKII_REDFISH_CREDENTIAL_STOP_SERVICE_TYPE
ServiceStopType
+ )
+{
+ EFI_STATUS Status;
+
+ if ((ServiceStopType <= ServiceStopTypeNone) || (ServiceStopType
+ >=
ServiceStopTypeMax)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Raise flag first
+ //
+ mRedfishServiceStopped = TRUE;
+
+ //
+ // Notify BMC to disable credential bootstrapping support.
+ //
+ Status = GetBootstrapAccountCredentials (TRUE, NULL, NULL); if
+ (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: fail to disable bootstrap credential:
+ %r\n",
__FUNCTION__, Status));
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Notification of Exit Boot Service.
+
+ @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL.
+**/
+VOID
+EFIAPI
+LibCredentialExitBootServicesNotify (
+ IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This
+ )
+{
+ //
+ // Stop the credential support when system is about to enter OS.
+ //
+ LibStopRedfishService (This, ServiceStopTypeExitBootService); }
+
+/**
+ Notification of End of DXe.
+
+ @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL.
+**/
+VOID
+EFIAPI
+LibCredentialEndOfDxeNotify (
+ IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This
+ )
+{
+ //
+ // Do nothing now.
+ // We can stop credential support when system reach end-of-dxe
+for security
reason.
+ //
+}
+
+/**
+ Function to retrieve temporary use credentials for the UEFI
+redfish client
[Chang, Abner]
We miss the functionality to disable bootstrap credential service in
the function description.

+
+ @param[in] DisableBootstrapControl
+ TRUE - Tell the BMC to disable the bootstrap credential
+ service to ensure no one else gains credentials
+ FALSE Allow the bootstrap
+ credential service to continue @param[out] BootstrapUsername
+ A pointer to a UTF-8 encoded
+ string for the credential
username
+ When DisableBootstrapControl
+ is TRUE, this pointer can be NULL
+
+ @param[out] BootstrapPassword
+ A pointer to a UTF-8 encoded
+ string for the credential
password
+ When DisableBootstrapControl
+ is TRUE, this pointer can be NULL
+
+ @retval EFI_SUCCESS Credentials were successfully fetched and
returned
+ @retval EFI_INVALID_PARAMETER BootstrapUsername or
BootstrapPassword is NULL when DisableBootstrapControl
+ is set to FALSE
+ @retval EFI_DEVICE_ERROR An IPMI failure occurred
[Chang, Abner]
The return status should also include the status of disabling
bootstrap credential.


+**/
+EFI_STATUS
+GetBootstrapAccountCredentials (
+ IN BOOLEAN DisableBootstrapControl,
+ IN OUT CHAR8 *BootstrapUsername, OPTIONAL
+ IN OUT CHAR8 *BootstrapPassword OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ IPMI_BOOTSTRAP_CREDENTIALS_COMMAND_DATA CommandData;
+ IPMI_BOOTSTRAP_CREDENTIALS_RESULT_RESPONSE ResponseData;
+ UINT32 ResponseSize;
+
+ if (!PcdGetBool (PcdIpmiFeatureEnable)) {
+ DEBUG ((DEBUG_ERROR, "%a: IPMI is not enabled! Unable to fetch
+ Redfish
credentials\n", __FUNCTION__));
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // NULL buffer check
+ //
+ if (!DisableBootstrapControl && ((BootstrapUsername == NULL) ||
(BootstrapPassword == NULL))) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DEBUG ((DEBUG_VERBOSE, "%a: Disable bootstrap control: 0x%x\n",
+ __FUNCTION__, DisableBootstrapControl));
+
+ //
+ // IPMI callout to NetFn 2C, command 02
+ // Request data:
+ // Byte 1: REDFISH_IPMI_GROUP_EXTENSION
+ // Byte 2: DisableBootstrapControl
+ //
+ CommandData.GroupExtensionId =
REDFISH_IPMI_GROUP_EXTENSION;
+ CommandData.DisableBootstrapControl = (DisableBootstrapControl ?
+ REDFISH_IPMI_BOOTSTRAP_CREDENTIAL_DISABLE :
+ REDFISH_IPMI_BOOTSTRAP_CREDENTIAL_ENABLE);
+
+ ResponseSize = sizeof (ResponseData);
+
+ //
+ // Response data:
+ // Byte 1 : Completion code
+ // Byte 2 : REDFISH_IPMI_GROUP_EXTENSION
+ // Byte 3-18 : Username
+ // Byte 19-34: Password
+ //
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_GROUP_EXT,
+ REDFISH_IPMI_GET_BOOTSTRAP_CREDENTIALS_CMD,
+ (UINT8 *)&CommandData,
+ sizeof (CommandData),
+ (UINT8 *)&ResponseData,
+ &ResponseSize
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: IPMI transaction failure.
+ Returning\n",
__FUNCTION__));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ } else {
+ if (ResponseData.CompletionCode != IPMI_COMP_CODE_NORMAL) {
+ if (ResponseData.CompletionCode ==
REDFISH_IPMI_COMP_CODE_BOOTSTRAP_CREDENTIAL_DISABLED) {
+ DEBUG ((DEBUG_ERROR, "%a: bootstrap credential support was
disabled\n", __FUNCTION__));
+ return EFI_ACCESS_DENIED;
+ }
+
+ DEBUG ((DEBUG_ERROR, "%a: Completion code = 0x%x.
+ Returning\n",
__FUNCTION__, ResponseData.CompletionCode));
+ return EFI_PROTOCOL_ERROR;
+ } else if (ResponseData.GroupExtensionId !=
REDFISH_IPMI_GROUP_EXTENSION) {
+ DEBUG ((DEBUG_ERROR, "%a: Group Extension Response = 0x%x.
Returning\n", __FUNCTION__, ResponseData.GroupExtensionId));
+ return EFI_DEVICE_ERROR;
+ } else {
+ if (BootstrapUsername != NULL) {
+ CopyMem (BootstrapUsername, ResponseData.Username,
USERNAME_MAX_LENGTH);
+ //
+ // Manually append null-terminator in case 16 characters
+ username
returned.
+ //
+ BootstrapUsername[USERNAME_MAX_LENGTH] = '\0';
+ }
+
+ if (BootstrapPassword != NULL) {
+ CopyMem (BootstrapPassword, ResponseData.Password,
PASSWORD_MAX_LENGTH);
+ //
+ // Manually append null-terminator in case 16 characters
+ password
returned.
+ //
+ BootstrapPassword[PASSWORD_MAX_LENGTH] = '\0';
+ }
+ }
+ }
+
+ return Status;
+}
+
+/**
+ Retrieve platform's Redfish authentication information.
+
+ This functions returns the Redfish authentication method together
+ with the user Id and password.
+ - For AuthMethodNone, the UserId and Password could be used for
+ HTTP
header authentication
+ as defined by RFC7235.
+ - For AuthMethodRedfishSession, the UserId and Password could be
+ used for
Redfish
+ session login as defined by Redfish API specification (DSP0266).
+
+ Callers are responsible for and freeing the returned string storage.
+
+ @param[in] This Pointer to
EDKII_REDFISH_CREDENTIAL_PROTOCOL instance.
+ @param[out] AuthMethod Type of Redfish authentication method.
+ @param[out] UserId The pointer to store the returned UserId
string.
+ @param[out] Password The pointer to store the returned
Password
string.
+
+ @retval EFI_SUCCESS Get the authentication information
successfully.
+ @retval EFI_ACCESS_DENIED SecureBoot is disabled after EndOfDxe.
+ @retval EFI_INVALID_PARAMETER This or AuthMethod or UserId or
Password is NULL.
+ @retval EFI_OUT_OF_RESOURCES There are not enough memory
resources.
+ @retval EFI_UNSUPPORTED Unsupported authentication method is
found.
+
+**/
+EFI_STATUS
+EFIAPI
+LibCredentialGetAuthInfo (
+ IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This,
+ OUT EDKII_REDFISH_AUTH_METHOD *AuthMethod,
+ OUT CHAR8 **UserId,
+ OUT CHAR8 **Password
+ )
+{
+ EFI_STATUS Status;
+
+ if ((AuthMethod == NULL) || (UserId == NULL) || (Password == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *UserId = NULL;
+ *Password = NULL;
+
+ if (mRedfishServiceStopped) {
+ DEBUG ((DEBUG_ERROR, "%a: credential service is stopped due to
+ security
reason\n", __FUNCTION__));
+ return EFI_ACCESS_DENIED;
+ }
+
+ *AuthMethod = AuthMethodHttpBasic;
+
+ *UserId = AllocateZeroPool (sizeof (CHAR8) * USERNAME_MAX_SIZE);
+ if
[Chang, Abner]
Allocation memory with the size (USERNAME_MAX_LENGTH + 1) for both
BootUsername and BootstrapPassword? Because the maximum number of
characters defined in the spec is USERNAME_MAX_LENGTH for the
user/password.


+ (*UserId == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ *Password = AllocateZeroPool (sizeof (CHAR8) *
+ PASSWORD_MAX_SIZE); if (*Password == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = GetBootstrapAccountCredentials (FALSE, *UserId,
+ *Password); if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: fail to get bootstrap credential:
+ %r\n",
__FUNCTION__, Status));
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
diff --git
a/RedfishPkg/Library/RedfishPlatformCredentialLib/RedfishPlatformCre
de
ntialLi
b.h
b/RedfishPkg/Library/RedfishPlatformCredentialLib/RedfishPlatformCre
de
ntialLi
b.h
new file mode 100644
index 0000000000..5b448e01be
--- /dev/null
+++ b/RedfishPkg/Library/RedfishPlatformCredentialLib/RedfishPlatfor
+++ mC
+++ re
+++ dentialLib.h
@@ -0,0 +1,75 @@
+/** @file
+*
+* Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights
reserved.
+*
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+#include <Uefi.h>
+#include <IndustryStandard/Ipmi.h>
+#include <Protocol/EdkIIRedfishCredential.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IpmiBaseLib.h>
+#include <Library/MemoryAllocationLib.h> #include
+<Library/RedfishCredentialLib.h>
+
+#define REDFISH_IPMI_GROUP_EXTENSION 0x52
+#define REDFISH_IPMI_GET_BOOTSTRAP_CREDENTIALS_CMD 0x02
+#define REDFISH_IPMI_BOOTSTRAP_CREDENTIAL_ENABLE 0xA5
+#define REDFISH_IPMI_BOOTSTRAP_CREDENTIAL_DISABLE 0x00
+#define
REDFISH_IPMI_COMP_CODE_BOOTSTRAP_CREDENTIAL_DISABLED
0x80
+
+//
+// Per Redfish Host Interface Specification 1.3, The maximum lenght
+of // username and password is 16 characters long.
+//
+#define USERNAME_MAX_LENGTH 16
+#define PASSWORD_MAX_LENGTH 16
+#define USERNAME_MAX_SIZE (USERNAME_MAX_LENGTH + 1) //
NULL
terminator
+#define PASSWORD_MAX_SIZE (PASSWORD_MAX_LENGTH + 1) //
NULL
terminator
+
+#pragma pack(1)
+///
+/// The definition of IPMI command to get bootstrap account
+credentials /// typedef struct {
+ UINT8 GroupExtensionId;
+ UINT8 DisableBootstrapControl;
+} IPMI_BOOTSTRAP_CREDENTIALS_COMMAND_DATA;
+
+///
+/// The response data of getting bootstrap credential /// typedef
+struct {
+ UINT8 CompletionCode;
+ UINT8 GroupExtensionId;
+ CHAR8 Username[USERNAME_MAX_LENGTH];
+ CHAR8 Password[PASSWORD_MAX_LENGTH];
+} IPMI_BOOTSTRAP_CREDENTIALS_RESULT_RESPONSE;
+
+#pragma pack()
+
+/**
+ Function to retrieve temporary use credentials for the UEFI
+redfish client
[Chang, Abner]
We miss the functionality to disable bootstrap credential service in
the function description.

+
+ @param[in] DisableBootstrapControl
+ TRUE - Tell the BMC to disable the bootstrap credential
+ service to ensure no one else gains credentials
+ FALSE Allow the bootstrap
+ credential service to continue @param[out] BootstrapUsername
+ A pointer to a UTF-8 encoded
+ string for the credential username
+
+ @param[out] BootstrapPassword
+ A pointer to a UTF-8 encoded
+ string for the credential password
+
+ @retval EFI_SUCCESS Credentials were successfully fetched and
returned
[Chang, Abner]
Or the bootstrap credential service is disabled successfully, right?

+ @retval EFI_DEVICE_ERROR An IPMI failure occurred
+**/
+EFI_STATUS
+GetBootstrapAccountCredentials (
+ IN BOOLEAN DisableBootstrapControl,
+ IN OUT CHAR8 *BootstrapUsername,
+ IN OUT CHAR8 *BootstrapPassword
+ );
diff --git
a/RedfishPkg/Library/RedfishPlatformCredentialLib/RedfishPlatformCre
de
ntialLi
b.inf
b/RedfishPkg/Library/RedfishPlatformCredentialLib/RedfishPlatformCre
de
ntialLi
b.inf
new file mode 100644
index 0000000000..a990d28363
--- /dev/null
+++ b/RedfishPkg/Library/RedfishPlatformCredentialLib/RedfishPlatfor
+++ mC
+++ re
+++ dentialLib.inf
@@ -0,0 +1,37 @@
+## @file
+#
+# Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights
reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+[Defines]
+ INF_VERSION = 0x0001000b
+ BASE_NAME = RedfishPlatformCredentialLib
+ FILE_GUID = 9C45D622-4C66-417F-814C-F76246D97233
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = RedfishPlatformCredentialLib
+
+[Sources]
+ RedfishPlatformCredentialLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ RedfishPkg/RedfishPkg.dec
+ IpmiFeaturePkg/IpmiFeaturePkg.dec
[Chang, Abner]
Could you please add a comment to the reference of IpmiFeaturePkg? We
have to give customers a notice that the dependence of "edk2-
platforms/Features/Intel/OutOfBandManagement/". They have to add the
path to PACKAGES_PATH. You also have to skip this dependence in the
RedfishPkg.yaml to avoid the CI error.

Another thing is I propose to move out IpmiFeaturePkg from edk2-
platforms/Features/Intel/OutOfBandManagement to edk2-
platforms/Features/ManageabilityPkg that also provides the
implementation of PLDM/MCTP/IPMI/KCS. I had an initial talk with
IpmiFeaturePkg owner and get the positive response on this proposal. I
will kick off the discussion on the dev mailing list. That is to say
this module may need a little bit change later, however that is good
to me having this implementation now.
Thanks
Abner
+
+[LibraryClasses]
+ UefiLib
+ DebugLib
+ IpmiBaseLib
+ MemoryAllocationLib
+ BaseMemoryLib
+
+[Pcd]
+ gIpmiFeaturePkgTokenSpaceGuid.PcdIpmiFeatureEnable
+
+[Depex]
+ TRUE
--
2.17.1




-The information contained in this message may be confidential and
proprietary to American Megatrends (AMI). This communication is
intended to be read only by the individual or entity to whom it is
addressed or by their designee. If the reader of this message is not
the intended recipient, you are on notice that any distribution of
this message, in any form, is strictly prohibited. Please promptly
notify the sender by reply e-mail or by telephone at 770-246-8600, and
then delete or destroy all copies of the transmission.










-The information contained in this message may be confidential and
proprietary to American Megatrends (AMI). This communication is
intended to be read only by the individual or entity to whom it is
addressed or by their designee. If the reader of this message is not
the intended recipient, you are on notice that any distribution of
this message, in any form, is strictly prohibited. Please promptly
notify the sender by reply e-mail or by telephone at 770-246-8600, and
then delete or destroy all copies of the transmission.



-The information contained in this message may be confidential and proprietary to American Megatrends (AMI). This communication is intended to be read only by the individual or entity to whom it is addressed or by their designee. If the reader of this message is not the intended recipient, you are on notice that any distribution of this message, in any form, is strictly prohibited. Please promptly notify the sender by reply e-mail or by telephone at 770-246-8600, and then delete or destroy all copies of the transmission.


Re: [PATCH 03/14] DynamicTablesPkg: Update CmObjParser for IORT Rev E.d

PierreGondois
 

Hi Sami,

On 10/26/22 14:34, Sami Mujawar wrote:
Hi Pierre,
I have one comment marked inline as [SAMI].
Other than that change this patch should be good.
Yes indeed, thanks for spotting it and for making the modification,

Regards,
Pierre

Regards,
Sami Mujawar
On 10/10/2022 10:20 am, Pierre.Gondois@... wrote:
From: Pierre Gondois <pierre.gondois@...>

commit de200b7e2c3c ("DynamicTablesPkg: Update ArmNameSpaceObjects for
IORT Rev E.d")
adds new CmObj structures and fields to the ArmNameSpaceObjects.
Update the CmObjectParser accordingly.

Signed-off-by: Pierre Gondois <Pierre.Gondois@...>
---
.../ConfigurationManagerObjectParser.c | 59 ++++++++++++++-----
1 file changed, 45 insertions(+), 14 deletions(-)

diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
index b46f19693bb5..80ebb0708661 100644
--- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
+++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
@@ -183,21 +183,23 @@ STATIC CONST CM_OBJ_PARSER CmArmFixedFeatureFlagsParser[] = {
STATIC CONST CM_OBJ_PARSER CmArmItsGroupNodeParser[] = {
{ "Token", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL },
{ "ItsIdCount", 4, "0x%x", NULL },
- { "ItsIdToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL }
+ { "ItsIdToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL },
+ { "Identifier", 4, "0x%x", NULL },
};
/** A parser for EArmObjNamedComponent.
*/
STATIC CONST CM_OBJ_PARSER CmArmNamedComponentNodeParser[] = {
- { "Token", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL },
- { "IdMappingCount", 4, "0x%x", NULL },
- { "IdMappingToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL },
- { "Flags", 4, "0x%x", NULL },
- { "CacheCoherent", 4, "0x%x", NULL },
- { "AllocationHints", 1, "0x%x", NULL },
- { "MemoryAccessFlags", 1, "0x%x", NULL },
- { "AddressSizeLimit", 1, "0x%x", NULL },
- { "ObjectName", sizeof (CHAR8 *), "%a", NULL }
+ { "Token", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL },
+ { "IdMappingCount", 4, "0x%x", NULL },
+ { "IdMappingToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL },
+ { "Flags", 4, "0x%x", NULL },
+ { "CacheCoherent", 4, "0x%x", NULL },
+ { "AllocationHints", 1, "0x%x", NULL },
+ { "MemoryAccessFlags", 1, "0x%x", NULL },
+ { "AddressSizeLimit", 1, "0x%x", NULL },
+ { "ObjectName", 1, NULL, PrintString },
[SAMI] I think the Length field for ObjectName should be "sizeof (CHAR8
*)" otherwise PrintCmObjDesc() would not advance to the next field
correctly/
If you agree, I will make this change locally before pushing the patch.
[/SAMI]

+ { "Identifier", 4, "0x%x", NULL },
};
/** A parser for EArmObjRootComplex.
@@ -211,7 +213,10 @@ STATIC CONST CM_OBJ_PARSER CmArmRootComplexNodeParser[] = {
{ "MemoryAccessFlags", 1, "0x%x", NULL },
{ "AtsAttribute", 4, "0x%x", NULL },
{ "PciSegmentNumber", 4, "0x%x", NULL },
- { "MemoryAddressSize", 1, "0x%x", NULL }
+ { "MemoryAddressSize", 1, "0x%x", NULL },
+ { "PasidCapabilities", 2, "0x%x", NULL },
+ { "Flags", 4, "0x%x", NULL },
+ { "Identifier", 4, "0x%x", NULL },
};
/** A parser for EArmObjSmmuV1SmmuV2.
@@ -231,7 +236,8 @@ STATIC CONST CM_OBJ_PARSER CmArmSmmuV1SmmuV2NodeParser[] = {
{ "SMMU_NSgIrpt", 4, "0x%x", NULL },
{ "SMMU_NSgIrptFlags", 4, "0x%x", NULL },
{ "SMMU_NSgCfgIrpt", 4, "0x%x", NULL },
- { "SMMU_NSgCfgIrptFlags", 4, "0x%x", NULL }
+ { "SMMU_NSgCfgIrptFlags", 4, "0x%x", NULL },
+ { "Identifier", 4, "0x%x", NULL },
};
/** A parser for EArmObjSmmuV3.
@@ -249,7 +255,8 @@ STATIC CONST CM_OBJ_PARSER CmArmSmmuV3NodeParser[] = {
{ "GerrInterrupt", 4, "0x%x", NULL },
{ "SyncInterrupt", 4, "0x%x", NULL },
{ "ProximityDomain", 4, "0x%x", NULL },
- { "DeviceIdMappingIndex", 4, "0x%x", NULL }
+ { "DeviceIdMappingIndex", 4, "0x%x", NULL },
+ { "Identifier", 4, "0x%x", NULL },
};
/** A parser for EArmObjPmcg.
@@ -261,7 +268,8 @@ STATIC CONST CM_OBJ_PARSER CmArmPmcgNodeParser[] = {
{ "BaseAddress", 8, "0x%llx", NULL },
{ "OverflowInterrupt", 4, "0x%x", NULL },
{ "Page1BaseAddress", 8, "0x%llx", NULL },
- { "ReferenceToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL }
+ { "ReferenceToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL },
+ { "Identifier", 4, "0x%x", NULL },
};
/** A parser for EArmObjGicItsIdentifierArray.
@@ -432,6 +440,25 @@ STATIC CONST CM_OBJ_PARSER CmPciInterruptMapInfoParser[] = {
ARRAY_SIZE (CmArmGenericInterruptParser) },
};
+/** A parser for EArmObjRmr.
+*/
+STATIC CONST CM_OBJ_PARSER CmArmRmrInfoParser[] = {
+ { "Token", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL },
+ { "IdMappingCount", 4, "0x%x", NULL },
+ { "IdMappingToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL },
+ { "Identifier", 4, "0x%x", NULL },
+ { "Flags", 4, "0x%x", NULL },
+ { "MemRangeDescCount", 4, "0x%x", NULL },
+ { "MemRangeDescToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL },
+};
+
+/** A parser for EArmObjMemoryRangeDescriptor.
+*/
+STATIC CONST CM_OBJ_PARSER CmArmMemoryRangeDescriptorInfoParser[] = {
+ { "BaseAddress", 8, "0x%llx", NULL },
+ { "Length", 8, "0x%llx", NULL },
+};
+
/** A parser for EArmObjCpcInfo.
*/
STATIC CONST CM_OBJ_PARSER CmArmCpcInfoParser[] = {
@@ -588,6 +615,10 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = {
ARRAY_SIZE (CmArmPciAddressMapInfoParser) },
{ "EArmObjPciInterruptMapInfo", CmPciInterruptMapInfoParser,
ARRAY_SIZE (CmPciInterruptMapInfoParser) },
+ { "EArmObjRmr", CmArmRmrInfoParser,
+ ARRAY_SIZE (CmArmRmrInfoParser) },
+ { "EArmObjMemoryRangeDescriptor", CmArmMemoryRangeDescriptorInfoParser,
+ ARRAY_SIZE (CmArmMemoryRangeDescriptorInfoParser) },
{ "EArmObjCpcInfo", CmArmCpcInfoParser,
ARRAY_SIZE (CmArmCpcInfoParser) },
{ "EArmObjMax", NULL, 0 },


Re: [PATCH 06/14] DynamicTablesPkg: Fix wrong/missing fields in CmObjParser

PierreGondois
 

Hi Sami,

On 10/26/22 14:34, Sami Mujawar wrote:
Hi Pierre,
I have one comment marked inline as [SAMI].
I believe other than that change this patch should be good.
Yes indeed, thanks for spotting it and for making the modification,

Regards,
Pierre


Regards,
Sami Mujawar
On 10/10/2022 10:20 am, Pierre.Gondois@... wrote:
From: Pierre Gondois <pierre.gondois@...>

Add missing fields to the following CmObjParser objects:
- EArmObjGicDInfo
- EArmObjCacheInfo
and fix wrong formatting of:
- EArmObjLpiInfo

Signed-off-by: Pierre Gondois <Pierre.Gondois@...>
---
.../ConfigurationManagerObjectParser.c | 24 ++++++++++---------
1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
index 040aaa4cbb17..2126beba8b9f 100644
--- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
+++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
@@ -303,7 +303,8 @@ STATIC CONST CM_OBJ_PARSER CmArmProcHierarchyInfoParser[] = {
{ "ParentToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL },
{ "GicCToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL },
{ "NoOfPrivateResources", 4, "0x%x", NULL },
- { "PrivateResourcesArrayToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL }
+ { "PrivateResourcesArrayToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL },
+ { "LpiToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL },
};
/** A parser for EArmObjCacheInfo.
@@ -315,7 +316,8 @@ STATIC CONST CM_OBJ_PARSER CmArmCacheInfoParser[] = {
{ "NumberOfSets", 4, "0x%x", NULL },
{ "Associativity", 4, "0x%x", NULL },
{ "Attributes", 1, "0x%x", NULL },
- { "LineSize", 2, "0x%x", NULL }
+ { "LineSize", 2, "0x%x", NULL },
+ { "CacheId", 4, "0x%x", NULL },
};
/** A parser for EArmObjProcNodeIdInfo.
@@ -400,14 +402,14 @@ STATIC CONST CM_OBJ_PARSER AcpiGenericAddressParser[] = {
/** A parser for EArmObjLpiInfo.
*/
STATIC CONST CM_OBJ_PARSER CmArmLpiInfoParser[] = {
- { "MinResidency", 4, "0x%x", NULL },
- { "WorstCaseWakeLatency", 4, "0x%x", NULL },
- { "Flags", 4, "0x%x", NULL },
- { "ArchFlags", 4, "0x%x", NULL },
- { "ResCntFreq", 4, "0x%x", NULL },
- { "EnableParentState", 4, "0x%x", NULL },
- { "IsInteger", 1, "%d", NULL },
- { "IntegerEntryMethod", 8, "0x%llx", NULL },
+ { "MinResidency", 4, "0x%x", NULL },
+ { "WorstCaseWakeLatency", 4, "0x%x", NULL },
+ { "Flags", 4, "0x%x", NULL },
+ { "ArchFlags", 4, "0x%x", NULL },
+ { "ResCntFreq", 4, "0x%x", NULL },
+ { "EnableParentState", 4, "0x%x", NULL },
+ { "IsInteger", 1, "%d", NULL },
+ { "IntegerEntryMethod", 8, "0x%llx", NULL },
{ "RegisterEntryMethod", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
NULL, NULL, AcpiGenericAddressParser,
ARRAY_SIZE (AcpiGenericAddressParser) },
@@ -417,7 +419,7 @@ STATIC CONST CM_OBJ_PARSER CmArmLpiInfoParser[] = {
{ "UsageCounterRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
NULL, NULL, AcpiGenericAddressParser,
ARRAY_SIZE (AcpiGenericAddressParser) },
- { "StateName", 16, "0x%a", NULL },
+ { "StateName", 16, "NULL", PrintString },
[SAMI] I think the format specifier should be NULL and not enclosed in
quotes. If you agree I will fix this before merging.
};
/** A parser for EArmObjPciAddressMapInfo.


Re: [PATCH 10/14] DynamicTablesPkg: Add PCCT related objects

PierreGondois
 

Hi Sami,

On 10/26/22 14:34, Sami Mujawar wrote:
Hi Pierre,
There are some minor updates that are required for this patch marked inline as [SAMI].
If you agree, I will make these changes before merging.
Yes indeed, thanks for spotting it and for making the modification,

Regards,
Pierre


Regards,
Sami Mujawar
On 10/10/2022 10:20 am, Pierre.Gondois@... wrote:
From: Pierre Gondois<pierre.gondois@...>

Introduce the following CmObj in the ArmNameSpaceObjects:
- CM_ARM_MAILBOX_REGISTER_INFO
- CM_ARM_PCC_SUBSPACE_CHANNEL_TIMING_INFO
- CM_ARM_PCC_SUBSPACE_GENERIC_INFO
- CM_ARM_PCC_SUBPSACE_TYPE0_INFO
- CM_ARM_PCC_SUBPSACE_TYPE1_INFO
- CM_ARM_PCC_SUBPSACE_TYPE2_INFO
- CM_ARM_PCC_SUBPSACE_TYPE3_INFO
- CM_ARM_PCC_SUBPSACE_TYPE4_INFO
- CM_ARM_PCC_SUBPSACE_TYPE5_INFO

These objects allow to describe mailbox registers, pcc timings
and PCCT subspaces. They prepare the enablement of a PCCT generator.

Also add the CmObjParsers associated to each object.

Signed-off-by: Pierre Gondois<Pierre.Gondois@...>
---
.../Include/ArmNameSpaceObjects.h | 277 +++++++++++++++---
.../ConfigurationManagerObjectParser.c | 107 +++++++
2 files changed, 341 insertions(+), 43 deletions(-)

diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
index d711f3ec5938..5d5a8ce92a09 100644
--- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
+++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
@@ -22,49 +22,55 @@
in the ARM Namespace
*/
typedef enum ArmObjectID {
- EArmObjReserved, ///< 0 - Reserved
- EArmObjBootArchInfo, ///< 1 - Boot Architecture Info
- EArmObjCpuInfo, ///< 2 - CPU Info
- EArmObjPowerManagementProfileInfo, ///< 3 - Power Management Profile Info
- EArmObjGicCInfo, ///< 4 - GIC CPU Interface Info
- EArmObjGicDInfo, ///< 5 - GIC Distributor Info
- EArmObjGicMsiFrameInfo, ///< 6 - GIC MSI Frame Info
- EArmObjGicRedistributorInfo, ///< 7 - GIC Redistributor Info
- EArmObjGicItsInfo, ///< 8 - GIC ITS Info
- EArmObjSerialConsolePortInfo, ///< 9 - Serial Console Port Info
- EArmObjSerialDebugPortInfo, ///< 10 - Serial Debug Port Info
- EArmObjGenericTimerInfo, ///< 11 - Generic Timer Info
- EArmObjPlatformGTBlockInfo, ///< 12 - Platform GT Block Info
- EArmObjGTBlockTimerFrameInfo, ///< 13 - Generic Timer Block Frame Info
- EArmObjPlatformGenericWatchdogInfo, ///< 14 - Platform Generic Watchdog
- EArmObjPciConfigSpaceInfo, ///< 15 - PCI Configuration Space Info
- EArmObjHypervisorVendorIdentity, ///< 16 - Hypervisor Vendor Id
- EArmObjFixedFeatureFlags, ///< 17 - Fixed feature flags for FADT
- EArmObjItsGroup, ///< 18 - ITS Group
- EArmObjNamedComponent, ///< 19 - Named Component
- EArmObjRootComplex, ///< 20 - Root Complex
- EArmObjSmmuV1SmmuV2, ///< 21 - SMMUv1 or SMMUv2
- EArmObjSmmuV3, ///< 22 - SMMUv3
- EArmObjPmcg, ///< 23 - PMCG
- EArmObjGicItsIdentifierArray, ///< 24 - GIC ITS Identifier Array
- EArmObjIdMappingArray, ///< 25 - ID Mapping Array
- EArmObjSmmuInterruptArray, ///< 26 - SMMU Interrupt Array
- EArmObjProcHierarchyInfo, ///< 27 - Processor Hierarchy Info
- EArmObjCacheInfo, ///< 28 - Cache Info
- EArmObjReserved29, ///< 29 - Reserved
- EArmObjCmRef, ///< 30 - CM Object Reference
- EArmObjMemoryAffinityInfo, ///< 31 - Memory Affinity Info
- EArmObjDeviceHandleAcpi, ///< 32 - Device Handle Acpi
- EArmObjDeviceHandlePci, ///< 33 - Device Handle Pci
- EArmObjGenericInitiatorAffinityInfo, ///< 34 - Generic Initiator Affinity
- EArmObjSerialPortInfo, ///< 35 - Generic Serial Port Info
- EArmObjCmn600Info, ///< 36 - CMN-600 Info
- EArmObjLpiInfo, ///< 37 - Lpi Info
- EArmObjPciAddressMapInfo, ///< 38 - Pci Address Map Info
- EArmObjPciInterruptMapInfo, ///< 39 - Pci Interrupt Map Info
- EArmObjRmr, ///< 40 - Reserved Memory Range Node
- EArmObjMemoryRangeDescriptor, ///< 41 - Memory Range Descriptor
- EArmObjCpcInfo, ///< 42 - Continuous Performance Control Info
+ EArmObjReserved, ///< 0 - Reserved
+ EArmObjBootArchInfo, ///< 1 - Boot Architecture Info
+ EArmObjCpuInfo, ///< 2 - CPU Info
+ EArmObjPowerManagementProfileInfo, ///< 3 - Power Management Profile Info
+ EArmObjGicCInfo, ///< 4 - GIC CPU Interface Info
+ EArmObjGicDInfo, ///< 5 - GIC Distributor Info
+ EArmObjGicMsiFrameInfo, ///< 6 - GIC MSI Frame Info
+ EArmObjGicRedistributorInfo, ///< 7 - GIC Redistributor Info
+ EArmObjGicItsInfo, ///< 8 - GIC ITS Info
+ EArmObjSerialConsolePortInfo, ///< 9 - Serial Console Port Info
+ EArmObjSerialDebugPortInfo, ///< 10 - Serial Debug Port Info
+ EArmObjGenericTimerInfo, ///< 11 - Generic Timer Info
+ EArmObjPlatformGTBlockInfo, ///< 12 - Platform GT Block Info
+ EArmObjGTBlockTimerFrameInfo, ///< 13 - Generic Timer Block Frame Info
+ EArmObjPlatformGenericWatchdogInfo, ///< 14 - Platform Generic Watchdog
+ EArmObjPciConfigSpaceInfo, ///< 15 - PCI Configuration Space Info
+ EArmObjHypervisorVendorIdentity, ///< 16 - Hypervisor Vendor Id
+ EArmObjFixedFeatureFlags, ///< 17 - Fixed feature flags for FADT
+ EArmObjItsGroup, ///< 18 - ITS Group
+ EArmObjNamedComponent, ///< 19 - Named Component
+ EArmObjRootComplex, ///< 20 - Root Complex
+ EArmObjSmmuV1SmmuV2, ///< 21 - SMMUv1 or SMMUv2
+ EArmObjSmmuV3, ///< 22 - SMMUv3
+ EArmObjPmcg, ///< 23 - PMCG
+ EArmObjGicItsIdentifierArray, ///< 24 - GIC ITS Identifier Array
+ EArmObjIdMappingArray, ///< 25 - ID Mapping Array
+ EArmObjSmmuInterruptArray, ///< 26 - SMMU Interrupt Array
+ EArmObjProcHierarchyInfo, ///< 27 - Processor Hierarchy Info
+ EArmObjCacheInfo, ///< 28 - Cache Info
+ EArmObjReserved29, ///< 29 - Reserved
+ EArmObjCmRef, ///< 30 - CM Object Reference
+ EArmObjMemoryAffinityInfo, ///< 31 - Memory Affinity Info
+ EArmObjDeviceHandleAcpi, ///< 32 - Device Handle Acpi
+ EArmObjDeviceHandlePci, ///< 33 - Device Handle Pci
+ EArmObjGenericInitiatorAffinityInfo, ///< 34 - Generic Initiator Affinity
+ EArmObjSerialPortInfo, ///< 35 - Generic Serial Port Info
+ EArmObjCmn600Info, ///< 36 - CMN-600 Info
+ EArmObjLpiInfo, ///< 37 - Lpi Info
+ EArmObjPciAddressMapInfo, ///< 38 - Pci Address Map Info
+ EArmObjPciInterruptMapInfo, ///< 39 - Pci Interrupt Map Info
+ EArmObjRmr, ///< 40 - Reserved Memory Range Node
+ EArmObjMemoryRangeDescriptor, ///< 41 - Memory Range Descriptor
+ EArmObjCpcInfo, ///< 42 - Continuous Performance Control Info
+ EArmObjPccSubspaceType0Info, ///< 43 - Pcc Subspace Type 0 Info
+ EArmObjPccSubspaceType1Info, ///< 44 - Pcc Subspace Type 2 Info
+ EArmObjPccSubspaceType2Info, ///< 45 - Pcc Subspace Type 2 Info
+ EArmObjPccSubspaceType3Info, ///< 46 - Pcc Subspace Type 3 Info
+ EArmObjPccSubspaceType4Info, ///< 47 - Pcc Subspace Type 4 Info
+ EArmObjPccSubspaceType5Info, ///< 48 - Pcc Subspace Type 5 Info
EArmObjMax
} EARM_OBJECT_ID;
@@ -1095,6 +1101,191 @@ typedef struct CmArmRmrDescriptor {
*/
typedef AML_CPC_INFO CM_ARM_CPC_INFO;
+/** A structure that describes a
+ PCC Mailbox Register.
+*/
+typedef struct PccMailboxRegisterInfo {
+ /// GAS describing the Register.
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE Register;
+
+ /** Mask of bits to preserve when writing.
+
+ This mask is also used for registers the Register is only read
[SAMI] I think the above line should be
This mask is also used for registers. The Register is only read
[/SAMI]

+ and there is no write mask required. E.g.:
+ - Error Status mask (Cf. PCC Subspace types 3/4/5).
+ - Command Complete Check mask (Cf. PCC Subspace types 3/4/5).
+ */
+ UINT64 PreserveMask;
+
+ /// Mask of bits to set when writing.
+ UINT64 WriteMask;
+} PCC_MAILBOX_REGISTER_INFO;
+
+/** A structure that describes the
+ PCC Subspace CHannel Timings.
+*/
+typedef struct PccSubspaceChannelTimingInfo {
+ /// Expected latency to process a command, in microseconds.
+ UINT32 NominalLatency;
+
+ /** Maximum number of periodic requests that the subspace channel can
+ support, reported in commands per minute. 0 indicates no limitation.
+
+ This field is ignored for the PCC Subspace type 5 (HW Registers based).
+ */
+ UINT32 MaxPeriodicAccessRate;
+
+ /** Minimum amount of time that OSPM must wait after the completion
+ of a command before issuing the next command, in microseconds.
+ */
+ UINT16 MinRequestTurnaroundTime;
+} PCC_SUBSPACE_CHANNEL_TIMING_INFO;
+
+/** A structure that describes a
+ Generic PCC Subspace (Type 0).
+*/
+typedef struct CmArmPccSubspaceGenericInfo {
+ /** Subspace Id.
+
+ Cf. ACPI 6.4, s14.7 Referencing the PCC address space
+ Cf. s14.1.2 Platform Communications Channel Subspace Structures
+ The subspace ID of a PCC subspace is its index in the array of
+ subspace structures, starting with subspace 0.
+
+ At most 256 subspaces are supported.
+ */
+ UINT8 SubspaceId;
+
+ /// Table type (or subspace).
+ UINT8 Type;
+
+ /// Base address of the shared memory range.
+ /// This field is ignored for the PCC Subspace type 5 (HW Registers based).
+ UINT64 BaseAddress;
+
+ /// Address length.
+ UINT64 AddressLength;
+
+ /// Doorbell Register.
+ PCC_MAILBOX_REGISTER_INFO DoorbellReg;
+
+ /// Mailbox Timings.
+ PCC_SUBSPACE_CHANNEL_TIMING_INFO ChannelTiming;
+} PCC_SUBSPACE_GENERIC_INFO;
+
+/** A structure that describes a
+ PCC Subspace of type 0 (Generic).
+
+ ID: EArmObjPccSubspaceType0Info
+*/
+typedef PCC_SUBSPACE_GENERIC_INFO CM_ARM_PCC_SUBSPACE_TYPE0_INFO;
+
+/** A structure that describes a
+ PCC Subspace of type 1 (HW-Reduced).
+
+ ID: EArmObjPccSubspaceType1Info
+*/
+typedef struct CmArmPccSubspaceType1Info {
+ /** Generic Pcc information.
+
+ The Subspace of Type0 contains information that can be re-used
+ in other Subspace types.
+ */
+ PCC_SUBSPACE_GENERIC_INFO GenericPccInfo;
+
+ /// Platform Interrupt.
+ CM_ARM_GENERIC_INTERRUPT PlatIrq;
+} CM_ARM_PCC_SUBSPACE_TYPE1_INFO;
+
+/** A structure that describes a
+ PCC Subspace of type 2 (HW-Reduced).
+
+ ID: EArmObjPccSubspaceType2Info
+*/
+typedef struct CmArmPccSubspaceType2Info {
+ /** Generic Pcc information.
+
+ The Subspace of Type0 contains information that can be re-used
+ in other Subspace types.
+ */
+ PCC_SUBSPACE_GENERIC_INFO GenericPccInfo;
+
+ /// Platform Interrupt.
+ CM_ARM_GENERIC_INTERRUPT PlatIrq;
+
+ /// Platform Interrupt Register.
+ PCC_MAILBOX_REGISTER_INFO PlatIrqAckReg;
+} CM_ARM_PCC_SUBSPACE_TYPE2_INFO;
+
+/** A structure that describes a
+ PCC Subspace of type 3 (Extended)
+
+ ID: EArmObjPccSubspaceType3Info
+*/
+typedef struct CmArmPccSubspaceType3Info {
+ /** Generic Pcc information.
+
+ The Subspace of Type0 contains information that can be re-used
+ in other Subspace types.
+ */
+ PCC_SUBSPACE_GENERIC_INFO GenericPccInfo;
+
+ /// Platform Interrupt.
+ CM_ARM_GENERIC_INTERRUPT PlatIrq;
+
+ /// Platform Interrupt Register.
+ PCC_MAILBOX_REGISTER_INFO PlatIrqAckReg;
+
+ /// Command Complete Check Register.
+ /// The WriteMask field is not used.
+ PCC_MAILBOX_REGISTER_INFO CmdCompleteCheckReg;
+
+ /// Command Complete Update Register.
+ PCC_MAILBOX_REGISTER_INFO CmdCompleteUpdateReg;
+
+ /// Error Status Register.
+ /// The WriteMask field is not used.
+ PCC_MAILBOX_REGISTER_INFO ErrorStatusReg;
+} CM_ARM_PCC_SUBSPACE_TYPE3_INFO;
+
+/** A structure that describes a
+ PCC Subspace of type 4 (Extended)
+
+ ID: EArmObjPccSubspaceType4Info
+*/
+typedef CM_ARM_PCC_SUBSPACE_TYPE3_INFO CM_ARM_PCC_SUBSPACE_TYPE4_INFO;
+
+/** A structure that describes a
+ PCC Subspace of type 5 (HW-Registers).
+
+ ID: EArmObjPccSubspaceType5Info
+*/
+typedef struct CmArmPccSubspaceType5Info {
+ /** Generic Pcc information.
+
+ The Subspace of Type0 contains information that can be re-used
+ in other Subspace types.
+
+ MaximumPeriodicAccessRate doesn't need to be populated for
+ this structure.
+ */
+ PCC_SUBSPACE_GENERIC_INFO GenericPccInfo;
+
+ /// Version.
+ UINT16 Version;
+
+ /// Platform Interrupt.
+ CM_ARM_GENERIC_INTERRUPT PlatIrq;
+
+ /// Command Complete Check Register.
+ /// The WriteMask field is not used.
+ PCC_MAILBOX_REGISTER_INFO CmdCompleteCheckReg;
+
+ /// Error Status Register.
+ /// The WriteMask field is not used.
+ PCC_MAILBOX_REGISTER_INFO ErrorStatusReg;
+} CM_ARM_PCC_SUBSPACE_TYPE5_INFO;
+
#pragma pack()
#endif // ARM_NAMESPACE_OBJECTS_H_
diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
index 2126beba8b9f..21d1f3f08b16 100644
--- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
+++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
@@ -539,6 +539,101 @@ STATIC CONST CM_OBJ_PARSER CmArmCpcInfoParser[] = {
{ "NominalFrequencyInteger", 4, "0x%lx", NULL },
};
+/** A parser for the CM_ARM_MAILBOX_REGISTER_INFO struct.
+*/
+STATIC CONST CM_OBJ_PARSER CmArmMailboxRegisterInfoParser[] = {
+ { "Register", sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE), NULL, NULL,
+ AcpiGenericAddressParser, ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "PreserveMask", 8, "0x%llx", NULL },
+ { "WriteMask", 8, "0x%llx", NULL },
+};
+
+/** A parser for the CM_ARM_PCC_SUBSPACE_CHANNEL_TIMING_INFO struct.
+*/
+STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceChannelTimingInfoParser[] = {
+ { "NominalLatency", 4, "0x%x", NULL },
+ { "MaxPeriodicAccessRate", 4, "0x%x", NULL },
+ { "MinRequestTurnaroundTime", 2, "0x%x", NULL },
+};
+
+/** A parser for EArmObjPccSubspaceType0Info.
+*/
+STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType0InfoParser[] = {
+ { "SubspaceId", 1, "0x%x", NULL },
+ { "Type", 1, "0x%x", NULL },
+ { "BaseAddress", 8, "0x%llx", NULL },
+ { "AddressLength", 8, "0x%llx", NULL },
+ { "DoorbellReg", sizeof (CM_ARM_MAILBOX_REGISTER_INFO),
+ NULL, NULL, CmArmMailboxRegisterInfoParser,
+ ARRAY_SIZE (CmArmMailboxRegisterInfoParser) },
+ { "DoorbellReg", sizeof (CM_ARM_PCC_SUBSPACE_CHANNEL_TIMING_INFO),
[SAMI] "DoorbellReg" should be changed to "ChannelTiming" above.
+ NULL, NULL, CmArmPccSubspaceChannelTimingInfoParser,
+ ARRAY_SIZE (CmArmPccSubspaceChannelTimingInfoParser) },
+};
+
+/** A parser for EArmObjPccSubspaceType1Info.
+*/
+STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType1InfoParser[] = {
+ { "GenericPccInfo", sizeof (CM_ARM_PCC_SUBSPACE_GENERIC_INFO),
+ NULL, NULL, CmArmPccSubspaceType0InfoParser,
+ ARRAY_SIZE (CmArmPccSubspaceType0InfoParser) },
+ { "PlatIrq", sizeof (CM_ARM_GENERIC_INTERRUPT),
+ NULL, NULL, CmArmGenericInterruptParser,
+ ARRAY_SIZE (CmArmGenericInterruptParser) },
+};
+
+/** A parser for EArmObjPccSubspaceType2Info.
+*/
+STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType2InfoParser[] = {
+ { "GenericPccInfo", sizeof (CM_ARM_PCC_SUBSPACE_GENERIC_INFO),
+ NULL, NULL, CmArmPccSubspaceType0InfoParser,
+ ARRAY_SIZE (CmArmPccSubspaceType0InfoParser) },
+ { "PlatIrq", sizeof (CM_ARM_GENERIC_INTERRUPT), NULL,NULL,
+ CmArmGenericInterruptParser, ARRAY_SIZE (CmArmGenericInterruptParser) },
+ { "PlatIrqAckReg", sizeof (CM_ARM_MAILBOX_REGISTER_INFO),
+ NULL, NULL, CmArmMailboxRegisterInfoParser,
+ ARRAY_SIZE (CmArmMailboxRegisterInfoParser) },
+};
+
+/** A parser for EArmObjPccSubspaceType3Info or EArmObjPccSubspaceType4Info.
+*/
+STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType34InfoParser[] = {
+ { "GenericPccInfo", sizeof (CM_ARM_PCC_SUBSPACE_GENERIC_INFO),
+ NULL, NULL, CmArmPccSubspaceType0InfoParser,
+ ARRAY_SIZE (CmArmPccSubspaceType0InfoParser) },
+ { "PlatIrq", sizeof (CM_ARM_GENERIC_INTERRUPT), NULL,NULL,
+ CmArmGenericInterruptParser, ARRAY_SIZE (CmArmGenericInterruptParser) },
+ { "PlatIrqAckReg", sizeof (CM_ARM_MAILBOX_REGISTER_INFO),
+ NULL, NULL, CmArmMailboxRegisterInfoParser,
+ ARRAY_SIZE (CmArmMailboxRegisterInfoParser) },
+ { "CmdCompleteCheckReg", sizeof (CM_ARM_MAILBOX_REGISTER_INFO),
+ NULL, NULL, CmArmMailboxRegisterInfoParser,
+ ARRAY_SIZE (CmArmMailboxRegisterInfoParser) },
+ { "CmdCompleteUpdateReg", sizeof (CM_ARM_MAILBOX_REGISTER_INFO),
+ NULL, NULL, CmArmMailboxRegisterInfoParser,
+ ARRAY_SIZE (CmArmMailboxRegisterInfoParser) },
+ { "ErrorStatusReg", sizeof (CM_ARM_MAILBOX_REGISTER_INFO),
+ NULL, NULL, CmArmMailboxRegisterInfoParser,
+ ARRAY_SIZE (CmArmMailboxRegisterInfoParser) },
+};
+
+/** A parser for EArmObjPccSubspaceType5Info.
+*/
+STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType5InfoParser[] = {
+ { "GenericPccInfo", sizeof (CM_ARM_PCC_SUBSPACE_GENERIC_INFO),
+ NULL, NULL, CmArmPccSubspaceType0InfoParser,
+ ARRAY_SIZE (CmArmPccSubspaceType0InfoParser) },
+ { "Version", 2, "0x%x",NULL },
+ { "PlatIrq", sizeof (CM_ARM_GENERIC_INTERRUPT), NULL, NULL,
+ CmArmGenericInterruptParser, ARRAY_SIZE (CmArmGenericInterruptParser) },
+ { "CmdCompleteCheckReg", sizeof (CM_ARM_MAILBOX_REGISTER_INFO),
+ NULL, NULL, CmArmMailboxRegisterInfoParser,
+ ARRAY_SIZE (CmArmMailboxRegisterInfoParser) },
+ { "ErrorStatusReg", sizeof (CM_ARM_MAILBOX_REGISTER_INFO),
+ NULL, NULL, CmArmMailboxRegisterInfoParser,
+ ARRAY_SIZE (CmArmMailboxRegisterInfoParser) },
+};
+
/** A parser for Arm namespace objects.
*/
STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = {
@@ -623,6 +718,18 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = {
ARRAY_SIZE (CmArmMemoryRangeDescriptorInfoParser) },
{ "EArmObjCpcInfo", CmArmCpcInfoParser,
ARRAY_SIZE (CmArmCpcInfoParser) },
+ { "EArmObjPccSubspaceType0Info", CmArmPccSubspaceType0InfoParser,
+ ARRAY_SIZE (CmArmPccSubspaceType0InfoParser) },
+ { "EArmObjPccSubspaceType1Info", CmArmPccSubspaceType1InfoParser,
+ ARRAY_SIZE (CmArmPccSubspaceType1InfoParser) },
+ { "EArmObjPccSubspaceType2Info", CmArmPccSubspaceType2InfoParser,
+ ARRAY_SIZE (CmArmPccSubspaceType2InfoParser) },
+ { "EArmObjPccSubspaceType3Info", CmArmPccSubspaceType34InfoParser,
+ ARRAY_SIZE (CmArmPccSubspaceType34InfoParser) },
+ { "EArmObjPccSubspaceType4Info", CmArmPccSubspaceType34InfoParser,
+ ARRAY_SIZE (CmArmPccSubspaceType34InfoParser) },
+ { "EArmObjPccSubspaceType5Info", CmArmPccSubspaceType5InfoParser,
+ ARRAY_SIZE (CmArmPccSubspaceType5InfoParser) },
{ "EArmObjMax", NULL, 0 },
};


Re: [PATCH 12/14] DynamicTablesPkg/AmlLib: Allow larger AccessSize for Pcc address space

PierreGondois
 

Hi Sami,

On 10/26/22 14:34, Sami Mujawar wrote:
Hi Pierre,
There are some minor changes required marked inline as [SAMI].
If you agree, I will make the changes before merging.
Yes indeed, thanks for spotting it and for making the modification,

Regards,
Pierre


Regards,
Sami Mujawar
On 10/10/2022 10:20 am, Pierre.Gondois@... wrote:
From: Pierre Gondois <pierre.gondois@...>

For Pcc address space, the AccessSize field of a Register is
used to delcare the Pcc Subspace Id. This Id can be up to 256.

Cf. ACPI 6.4, s14.7 Referencing the PCC address space

Signed-off-by: Pierre Gondois <Pierre.Gondois@...>
---
.../Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c
index 332962bed441..3901b6e47333 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c
@@ -1257,7 +1257,12 @@ AmlCodeGenRdRegister (
AML_DATA_NODE *RdNode;
EFI_ACPI_GENERIC_REGISTER_DESCRIPTOR RdRegister;
- if ((AccessSize > EFI_ACPI_6_4_QWORD) ||
+ // Cf Cf. ACPI 6.4, s14.7 Referencing the PCC address space
[SAMI] Cf appears twice.
+ // The AccessSize represents the Subspace Id for the PCC address space.
+ if (((AddressSpace == EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL) &&
+ (AccessSize > 256)) ||
+ ((AddressSpace != EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL) &&
[SAMI] Change EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL to
EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL.
+ (AccessSize > EFI_ACPI_6_4_QWORD)) ||
((NameOpNode == NULL) && (NewRdNode == NULL)))
{
ASSERT (0);


Re: [PATCH 11/14] DynamicTablesPkg: Add PCCT Generator

PierreGondois
 

Hi Sami,

On 10/26/22 14:35, Sami Mujawar wrote:
Hi Pierre,
There is a change required for this patch marked inline as [SAMI].
If you agree, I will make the changes before merging.
Yes indeed, this is a rebase error,
thanks for spotting it,

Regards,
Pierre

Regards,
Sami Mujawar
On 10/10/2022 10:20 am, Pierre.Gondois@... wrote:
From: Pierre Gondois <pierre.gondois@...>

The Platform Communication Channel Table (PCCT) generator collates
the relevant information required for generating a PCCT table from
configuration manager using the configuration manager protocol.
The DynamicTablesManager then install the PCCT table.

From ACPI 6.4, s14 PLATFORM COMMUNICATIONS CHANNEL (PCC):
The platform communication channel (PCC) is a generic mechanism
for OSPM to communicate with an entity in the platform.

Signed-off-by: Pierre Gondois <pierre.gondois@...>
---
DynamicTablesPkg/DynamicTables.dsc.inc | 4 +-
DynamicTablesPkg/Include/AcpiTableGenerator.h | 3 +-
.../Arm/AcpiPcctLibArm/AcpiPcctLibArm.inf | 30 +
.../Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c | 1186 +++++++++++++++++
.../Acpi/Arm/AcpiPcctLibArm/PcctGenerator.h | 43 +
.../ConfigurationManagerObjectParser.c | 46 +-
6 files changed, 1287 insertions(+), 25 deletions(-)
create mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/AcpiPcctLibArm.inf
create mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c
create mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.h

diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/DynamicTables.dsc.inc
index 3d4fa0c4c4b6..3e38fa0d0d99 100644
--- a/DynamicTablesPkg/DynamicTables.dsc.inc
+++ b/DynamicTablesPkg/DynamicTables.dsc.inc
@@ -1,7 +1,7 @@
## @file
# Dsc include file for Dynamic Tables Framework.
#
-# Copyright (c) 2017 - 2021, Arm Limited. All rights reserved.<BR>
+# Copyright (c) 2017 - 2022, Arm Limited. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -33,6 +33,7 @@ [Components.common]
DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf
DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf
DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/AcpiSratLibArm.inf
+ DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/AcpiPcctLibArm.inf
# AML Fixup
DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortLibArm.inf
@@ -57,6 +58,7 @@ [Components.common]
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/AcpiSratLibArm.inf
+ NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/AcpiPcctLibArm.inf
# AML Fixup
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortLibArm.inf
diff --git a/DynamicTablesPkg/Include/AcpiTableGenerator.h b/DynamicTablesPkg/Include/AcpiTableGenerator.h
index f962dbff57df..d0eda011c301 100644
--- a/DynamicTablesPkg/Include/AcpiTableGenerator.h
+++ b/DynamicTablesPkg/Include/AcpiTableGenerator.h
@@ -1,6 +1,6 @@
/** @file
- Copyright (c) 2017 - 2021, Arm Limited. All rights reserved.<BR>
+ Copyright (c) 2017 - 2022, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -98,6 +98,7 @@ typedef enum StdAcpiTableId {
EStdAcpiTableIdSsdtCmn600, ///< SSDT Cmn-600 Generator
EStdAcpiTableIdSsdtCpuTopology, ///< SSDT Cpu Topology
EStdAcpiTableIdSsdtPciExpress, ///< SSDT Pci Express Generator
+ EStdAcpiTableIdPcct, ///< PCCT Generator
EStdAcpiTableIdMax
} ESTD_ACPI_TABLE_ID;
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/AcpiPcctLibArm.inf b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/AcpiPcctLibArm.inf
new file mode 100644
index 000000000000..da54585c2dd9
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/AcpiPcctLibArm.inf
@@ -0,0 +1,30 @@
+## @file
+# Pcct Table Generator
+#
+# Copyright (c) 2022, Arm Limited. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = AcpiPcctLibArm
+ FILE_GUID = 38FE945C-D6ED-4CD6-8D20-FCEF3260D15A
+ VERSION_STRING = 1.0
+ MODULE_TYPE = DXE_DRIVER
+ LIBRARY_CLASS = NULL|DXE_DRIVER
+ CONSTRUCTOR = AcpiPcctLibConstructor
+ DESTRUCTOR = AcpiPcctLibDestructor
+
+[Sources]
+ PcctGenerator.c
+ PcctGenerator.h
+
+[Packages]
+ DynamicTablesPkg/DynamicTablesPkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ BaseLib
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c
new file mode 100644
index 000000000000..36caf4aaeab7
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.c
@@ -0,0 +1,1186 @@
+/** @file
+ PCCT Table Generator
+
+ Copyright (c) 2022, Arm Limited. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - ACPI 6.4 Specification - January 2021
+ s14 PLATFORM COMMUNICATIONS CHANNEL (PCC)
+
+**/
+
+#include <Library/AcpiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Protocol/AcpiTable.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <Library/TableHelperLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+#include "PcctGenerator.h"
+
+/** ARM standard PCCT Generator
+
+Requirements:
+ The following Configuration Manager Object(s) are required by
+ this Generator:
+ - EArmObjPccSubspaceType0Info
+ - EArmObjPccSubspaceType1Info
+ - EArmObjPccSubspaceType2Info
+ - EArmObjPccSubspaceType3Info
+ - EArmObjPccSubspaceType4Info
+ - EArmObjPccSubspaceType5Info
+*/
+
+/** This macro expands to a function that retrieves the PCC
+ Subspace of Type 0 Information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjPccSubspaceType0Info,
+ CM_ARM_PCC_SUBSPACE_TYPE0_INFO
+ );
+
+/** This macro expands to a function that retrieves the PCC
+ Subspace of Type 1 Information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjPccSubspaceType1Info,
+ CM_ARM_PCC_SUBSPACE_TYPE1_INFO
+ );
+
+/** This macro expands to a function that retrieves the PCC
+ Subspace of Type 2 Information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjPccSubspaceType2Info,
+ CM_ARM_PCC_SUBSPACE_TYPE2_INFO
+ );
+
+/** This macro expands to a function that retrieves the PCC
+ Subspace of Type 3 Information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjPccSubspaceType3Info,
+ CM_ARM_PCC_SUBSPACE_TYPE3_INFO
+ );
+
+/** This macro expands to a function that retrieves the PCC
+ Subspace of Type 4 Information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjPccSubspaceType4Info,
+ CM_ARM_PCC_SUBSPACE_TYPE4_INFO
+ );
+
+/** This macro expands to a function that retrieves the PCC
+ Subspace of Type 5 Information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjPccSubspaceType5Info,
+ CM_ARM_PCC_SUBSPACE_TYPE5_INFO
+ );
+
+/** The Platform is capable of generating an interrupt
+ to indicate completion of a command.
+
+ Cf: s14.1.1 Platform Communications Channel Global Flags
+ Platform Interrupt flag
+ and s14.1.6 Extended PCC subspaces (types 3 and 4)
+ If a responder subspace is included in the PCCT,
+ then the global Platform Interrupt flag must be set to 1
+
+ Set this variable and populate the PCCT flag accordingly if either:
+ - One of the PCCT Subspace uses interrupts.
+ - A PCC Subspace of type 4 is used.
+*/
+STATIC BOOLEAN mHasPlatformInterrupt;
+
+/** Initialize the MappingTable.
+
+ @param [in] MappingTable The mapping table structure.
+ @param [in] Count Number of entries to allocate in the
+ MappingTable.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+MappingTableInitialize (
+ IN MAPPING_TABLE *MappingTable,
+ IN UINT32 Count
+ )
+{
+ VOID **Table;
+
+ if ((MappingTable == NULL) ||
+ (Count == 0))
+ {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Table = AllocateZeroPool (sizeof (*Table) * Count);
+ if (Table == NULL) {
+ ASSERT (0);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ MappingTable->Table = Table;
+ MappingTable->MaxIndex = Count;
+
+ return EFI_SUCCESS;
+}
+
+/** Free the MappingTable.
+
+ @param [in, out] MappingTable The mapping table structure.
+**/
+STATIC
+VOID
+EFIAPI
+MappingTableFree (
+ IN OUT MAPPING_TABLE *MappingTable
+ )
+{
+ ASSERT (MappingTable != NULL);
+ ASSERT (MappingTable->Table != NULL);
+
+ if (MappingTable->Table != NULL) {
+ FreePool (MappingTable->Table);
+ }
+}
+
+/** Add a new entry for CmArmPccSubspace at Index.
+
+ @param [in] MappingTable The mapping table structure.
+ @param [in] CmArmPccSubspace Pointer to a CM_ARM_PCC_SUBSPACE_TYPE[X]_INFO.
+ @param [in] Index Index at which CmArmPccSubspace must be added.
+ This is the Subspace Id.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_BUFFER_TOO_SMALL Buffer too small.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+MappingTableAdd (
+ IN MAPPING_TABLE *MappingTable,
+ IN VOID *CmArmPccSubspace,
+ IN UINT32 Index
+ )
+{
+ if ((MappingTable == NULL) ||
+ (MappingTable->Table == NULL) ||
+ (CmArmPccSubspace == NULL))
+ {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((Index >= MappingTable->MaxIndex) ||
+ (MappingTable->Table[Index] != 0))
+ {
+ ASSERT_EFI_ERROR (EFI_BUFFER_TOO_SMALL);
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ // Just map the Pcc Subspace in the Table.
+ MappingTable->Table[Index] = CmArmPccSubspace;
+ return EFI_SUCCESS;
+}
+
+/** Parse the CmPccArray objects and add them to the MappingTable.
+
+ @param [in] MappingTable The mapping table structure.
+ @param [in] CmPccArray Pointer to an array of CM_ARM_PCC_SUBSPACE_TYPE[X]_INFO.
+ @param [in] CmPccCount Count of objects in CmPccArray.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_BUFFER_TOO_SMALL Buffer too small.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+MapPccSubspaceId (
+ IN MAPPING_TABLE *MappingTable,
+ IN VOID *CmPccArray,
+ IN UINT32 CmPccCount
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *PccBuffer;
+ UINT32 Index;
+ UINT32 CmObjSize;
+ PCC_SUBSPACE_GENERIC_INFO *GenericPcc;
+
+ if (CmPccCount == 0) {
+ return EFI_SUCCESS;
+ }
+
+ if ((CmPccArray == NULL) || (MappingTable == NULL)) {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ GenericPcc = (PCC_SUBSPACE_GENERIC_INFO *)CmPccArray;
+
+ switch (GenericPcc->Type) {
+ case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_GENERIC:
+ CmObjSize = sizeof (CM_ARM_PCC_SUBSPACE_TYPE0_INFO);
+ break;
+
+ case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS:
+ CmObjSize = sizeof (CM_ARM_PCC_SUBSPACE_TYPE1_INFO);
+ break;
+
+ case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS:
+ CmObjSize = sizeof (CM_ARM_PCC_SUBSPACE_TYPE2_INFO);
+ break;
+
+ case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC:
+ CmObjSize = sizeof (CM_ARM_PCC_SUBSPACE_TYPE3_INFO);
+ break;
+
+ case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC:
+ CmObjSize = sizeof (CM_ARM_PCC_SUBSPACE_TYPE4_INFO);
+ break;
+
+ case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_5_HW_REGISTERS_COMMUNICATIONS:
+ CmObjSize = sizeof (CM_ARM_PCC_SUBSPACE_TYPE5_INFO);
+ break;
+
+ default:
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PccBuffer = (UINT8 *)CmPccArray;
+
+ // Map the Pcc channel to their Subspace Id.
+ for (Index = 0; Index < CmPccCount; Index++) {
+ GenericPcc = (PCC_SUBSPACE_GENERIC_INFO *)PccBuffer;
+
+ Status = MappingTableAdd (
+ MappingTable,
+ PccBuffer,
+ GenericPcc->SubspaceId
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ PccBuffer += CmObjSize;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/** Add one PCCT Subspace structure of Type 0 (Generic).
+
+ @param [in] PccCmObj Pointer to a CmObj PCCT Subspace info structure.
+ @param [in] PccAcpi Pointer to the ACPI PCCT Subspace structure to populate.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+AddSubspaceStructType0 (
+ IN CM_ARM_PCC_SUBSPACE_TYPE0_INFO *PccCmObj,
+ IN EFI_ACPI_6_4_PCCT_SUBSPACE_GENERIC *PccAcpi
+ )
+{
+ PCC_MAILBOX_REGISTER_INFO *Doorbell;
+ PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming;
+
+ if ((PccCmObj == NULL) ||
+ (PccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_GENERIC) ||
+ (PccAcpi == NULL))
+ {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Doorbell = &PccCmObj->DoorbellReg;
+ ChannelTiming = &PccCmObj->ChannelTiming;
+
+ PccAcpi->Type = PccCmObj->Type;
+ PccAcpi->Length = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_GENERIC);
+ *(UINT32 *)&PccAcpi->Reserved[0] = EFI_ACPI_RESERVED_DWORD;
+ *(UINT16 *)&PccAcpi->Reserved[4] = EFI_ACPI_RESERVED_WORD;
+ PccAcpi->BaseAddress = PccCmObj->BaseAddress;
+ PccAcpi->AddressLength = PccCmObj->AddressLength;
+
+ CopyMem (
+ &PccAcpi->DoorbellRegister,
+ &Doorbell->Register,
+ sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE)
+ );
+ PccAcpi->DoorbellPreserve = Doorbell->PreserveMask;
+ PccAcpi->DoorbellWrite = Doorbell->WriteMask;
+
+ PccAcpi->NominalLatency = ChannelTiming->NominalLatency;
+ PccAcpi->MaximumPeriodicAccessRate = ChannelTiming->MaxPeriodicAccessRate;
+ PccAcpi->MinimumRequestTurnaroundTime = ChannelTiming->MinRequestTurnaroundTime;
+
+ return EFI_SUCCESS;
+}
+
+/** Add one PCCT subspace structure of Type 1 (HW-Reduced).
+
+ @param [in] PccCmObj Pointer to a CmObj PCCT Subspace info structure.
+ @param [in] PccAcpi Pointer to the ACPI PCCT Subspace structure to populate.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+AddSubspaceStructType1 (
+ IN CM_ARM_PCC_SUBSPACE_TYPE1_INFO *PccCmObj,
+ IN EFI_ACPI_6_4_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS *PccAcpi
+ )
+{
+ CM_ARM_PCC_SUBSPACE_TYPE0_INFO *GenericPccCmObj;
+ PCC_MAILBOX_REGISTER_INFO *Doorbell;
+ PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming;
+
+ GenericPccCmObj = (CM_ARM_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj;
+
+ if ((PccCmObj == NULL) ||
+ (GenericPccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS) ||
+ (PccAcpi == NULL))
+ {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Doorbell = &GenericPccCmObj->DoorbellReg;
+ ChannelTiming = &GenericPccCmObj->ChannelTiming;
+
+ PccAcpi->Type = GenericPccCmObj->Type;
+ PccAcpi->Length = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS);
+ PccAcpi->PlatformInterrupt = PccCmObj->PlatIrq.Interrupt;
+ PccAcpi->PlatformInterruptFlags = PccCmObj->PlatIrq.Flags;
+ PccAcpi->Reserved = EFI_ACPI_RESERVED_BYTE;
+ PccAcpi->BaseAddress = GenericPccCmObj->BaseAddress;
+ PccAcpi->AddressLength = GenericPccCmObj->AddressLength;
+
+ CopyMem (
+ &PccAcpi->DoorbellRegister,
+ &Doorbell->Register,
+ sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE)
+ );
+ PccAcpi->DoorbellPreserve = Doorbell->PreserveMask;
+ PccAcpi->DoorbellWrite = Doorbell->WriteMask;
+
+ PccAcpi->NominalLatency = ChannelTiming->NominalLatency;
+ PccAcpi->MaximumPeriodicAccessRate = ChannelTiming->MaxPeriodicAccessRate;
+ PccAcpi->MinimumRequestTurnaroundTime = ChannelTiming->MinRequestTurnaroundTime;
+
+ if ((PccCmObj->PlatIrq.Interrupt != 0)) {
+ mHasPlatformInterrupt = TRUE;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/** Add one PCCT subspace structure of Type 2 (HW-Reduced).
+
+ @param [in] PccCmObj Pointer to a CmObj PCCT Subspace info structure.
+ @param [in] PccAcpi Pointer to the ACPI PCCT Subspace structure to populate.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+AddSubspaceStructType2 (
+ IN CM_ARM_PCC_SUBSPACE_TYPE2_INFO *PccCmObj,
+ IN EFI_ACPI_6_4_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS *PccAcpi
+ )
+{
+ CM_ARM_PCC_SUBSPACE_TYPE0_INFO *GenericPccCmObj;
+ PCC_MAILBOX_REGISTER_INFO *Doorbell;
+ PCC_MAILBOX_REGISTER_INFO *PlatIrqAck;
+ PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming;
+
+ GenericPccCmObj = (CM_ARM_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj;
+
+ if ((PccCmObj == NULL) ||
+ (GenericPccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS) ||
+ (PccAcpi == NULL))
+ {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Doorbell = &GenericPccCmObj->DoorbellReg;
+ PlatIrqAck = &PccCmObj->PlatIrqAckReg;
+ ChannelTiming = &GenericPccCmObj->ChannelTiming;
+
+ PccAcpi->Type = GenericPccCmObj->Type;
+ PccAcpi->Length = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS);
+ PccAcpi->PlatformInterrupt = PccCmObj->PlatIrq.Interrupt;
+ PccAcpi->PlatformInterruptFlags = PccCmObj->PlatIrq.Flags;
+ PccAcpi->BaseAddress = GenericPccCmObj->BaseAddress;
+ PccAcpi->Reserved = EFI_ACPI_RESERVED_BYTE;
+ PccAcpi->BaseAddress = GenericPccCmObj->BaseAddress;
+ PccAcpi->AddressLength = GenericPccCmObj->AddressLength;
+
+ CopyMem (
+ &PccAcpi->DoorbellRegister,
+ &Doorbell->Register,
+ sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE)
+ );
+ PccAcpi->DoorbellPreserve = Doorbell->PreserveMask;
+ PccAcpi->DoorbellWrite = Doorbell->WriteMask;
+
+ PccAcpi->NominalLatency = ChannelTiming->NominalLatency;
+ PccAcpi->MaximumPeriodicAccessRate = ChannelTiming->MaxPeriodicAccessRate;
+ PccAcpi->MinimumRequestTurnaroundTime = ChannelTiming->MinRequestTurnaroundTime;
+
+ CopyMem (
+ &PccAcpi->PlatformInterruptAckRegister,
+ &PlatIrqAck->Register,
+ sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE)
+ );
+ PccAcpi->PlatformInterruptAckPreserve = PlatIrqAck->PreserveMask;
+ PccAcpi->PlatformInterruptAckWrite = PlatIrqAck->WriteMask;
+
+ if ((PccCmObj->PlatIrq.Interrupt != 0)) {
+ mHasPlatformInterrupt = TRUE;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/** Add one PCCT subspace structure of Type 3 or 4 (Extended).
+
+ @param [in] PccCmObj Pointer to a CmObj PCCT Subspace info structure.
+ @param [in] PccAcpi Pointer to the ACPI PCCT Subspace structure to populate.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+AddSubspaceStructType34 (
+ IN CM_ARM_PCC_SUBSPACE_TYPE3_INFO *PccCmObj,
+ IN EFI_ACPI_6_4_PCCT_SUBSPACE_3_EXTENDED_PCC *PccAcpi
+ )
+{
+ CM_ARM_PCC_SUBSPACE_TYPE0_INFO *GenericPccCmObj;
+ PCC_MAILBOX_REGISTER_INFO *Doorbell;
+ PCC_MAILBOX_REGISTER_INFO *PlatIrqAck;
+ PCC_MAILBOX_REGISTER_INFO *CmdCompleteCheck;
+ PCC_MAILBOX_REGISTER_INFO *CmdCompleteUpdate;
+ PCC_MAILBOX_REGISTER_INFO *ErrorStatus;
+ PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming;
+
+ GenericPccCmObj = (CM_ARM_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj;
+
+ if ((PccCmObj == NULL) ||
+ ((GenericPccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC) &&
+ (GenericPccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC)) ||
+ (PccAcpi == NULL))
+ {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Doorbell = &GenericPccCmObj->DoorbellReg;
+ PlatIrqAck = &PccCmObj->PlatIrqAckReg;
+ CmdCompleteCheck = &PccCmObj->CmdCompleteCheckReg;
+ CmdCompleteUpdate = &PccCmObj->CmdCompleteUpdateReg;
+ ErrorStatus = &PccCmObj->ErrorStatusReg;
+ ChannelTiming = &GenericPccCmObj->ChannelTiming;
+
+ PccAcpi->Type = GenericPccCmObj->Type;
+ PccAcpi->Length = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_3_EXTENDED_PCC);
+ PccAcpi->PlatformInterrupt = PccCmObj->PlatIrq.Interrupt;
+ PccAcpi->PlatformInterruptFlags = PccCmObj->PlatIrq.Flags;
+ PccAcpi->Reserved = EFI_ACPI_RESERVED_BYTE;
+ PccAcpi->BaseAddress = GenericPccCmObj->BaseAddress;
+ PccAcpi->AddressLength = GenericPccCmObj->AddressLength;
+
+ CopyMem (
+ &PccAcpi->DoorbellRegister,
+ &Doorbell->Register,
+ sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE)
+ );
+ PccAcpi->DoorbellPreserve = Doorbell->PreserveMask;
+ PccAcpi->DoorbellWrite = Doorbell->WriteMask;
+
+ PccAcpi->NominalLatency = ChannelTiming->NominalLatency;
+ PccAcpi->MaximumPeriodicAccessRate = ChannelTiming->MaxPeriodicAccessRate;
+ PccAcpi->MinimumRequestTurnaroundTime = ChannelTiming->MinRequestTurnaroundTime;
+
+ CopyMem (
+ &PccAcpi->PlatformInterruptAckRegister,
+ &PlatIrqAck->Register,
+ sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE)
+ );
+ PccAcpi->PlatformInterruptAckPreserve = PlatIrqAck->PreserveMask;
+ PccAcpi->PlatformInterruptAckSet = PlatIrqAck->WriteMask;
+
+ PccAcpi->Reserved1[0] = EFI_ACPI_RESERVED_BYTE;
+ PccAcpi->Reserved1[1] = EFI_ACPI_RESERVED_BYTE;
+ PccAcpi->Reserved1[1] = EFI_ACPI_RESERVED_BYTE;
+ PccAcpi->Reserved1[3] = EFI_ACPI_RESERVED_BYTE;
+ PccAcpi->Reserved1[4] = EFI_ACPI_RESERVED_BYTE;
+ PccAcpi->Reserved1[5] = EFI_ACPI_RESERVED_BYTE;
+ PccAcpi->Reserved1[6] = EFI_ACPI_RESERVED_BYTE;
+ PccAcpi->Reserved1[7] = EFI_ACPI_RESERVED_BYTE;
+
+ CopyMem (
+ &PccAcpi->CommandCompleteCheckRegister,
+ &CmdCompleteCheck->Register,
+ sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE)
+ );
+ PccAcpi->CommandCompleteCheckMask = CmdCompleteCheck->PreserveMask;
+ // No Write mask.
+
+ CopyMem (
+ &PccAcpi->CommandCompleteUpdateRegister,
+ &CmdCompleteUpdate->Register,
+ sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE)
+ );
+ PccAcpi->CommandCompleteUpdatePreserve = CmdCompleteUpdate->PreserveMask;
+ PccAcpi->CommandCompleteUpdateSet = CmdCompleteUpdate->WriteMask;
+
+ CopyMem (
+ &PccAcpi->ErrorStatusRegister,
+ &ErrorStatus->Register,
+ sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE)
+ );
+ PccAcpi->ErrorStatusMask = ErrorStatus->PreserveMask;
+ // No Write mask.
+
+ if (GenericPccCmObj->Type == EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC) {
+ mHasPlatformInterrupt = TRUE;
+ } else if ((PccCmObj->PlatIrq.Interrupt != 0)) {
+ mHasPlatformInterrupt = TRUE;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/** Add one PCCT subspace structure of Type 5 (HW-Registers).
+
+ @param [in] PccCmObj Pointer to a CmObj PCCT Subspace info structure.
+ @param [in] PccAcpi Pointer to the ACPI PCCT Subspace structure to populate.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+AddSubspaceStructType5 (
+ IN CM_ARM_PCC_SUBSPACE_TYPE5_INFO *PccCmObj,
+ IN EFI_ACPI_6_4_PCCT_SUBSPACE_5_HW_REGISTERS_COMMUNICATIONS *PccAcpi
+ )
+{
+ CM_ARM_PCC_SUBSPACE_TYPE0_INFO *GenericPccCmObj;
+ PCC_MAILBOX_REGISTER_INFO *Doorbell;
+ PCC_MAILBOX_REGISTER_INFO *CmdCompleteCheck;
+ PCC_MAILBOX_REGISTER_INFO *ErrorStatus;
+ PCC_SUBSPACE_CHANNEL_TIMING_INFO *ChannelTiming;
+
+ GenericPccCmObj = (CM_ARM_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj;
+
+ if ((PccCmObj == NULL) ||
+ (GenericPccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_5_HW_REGISTERS_COMMUNICATIONS) ||
+ (PccAcpi == NULL))
+ {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Doorbell = &GenericPccCmObj->DoorbellReg;
+ CmdCompleteCheck = &PccCmObj->CmdCompleteCheckReg;
+ ErrorStatus = &PccCmObj->ErrorStatusReg;
+ ChannelTiming = &GenericPccCmObj->ChannelTiming;
+
+ PccAcpi->Type = GenericPccCmObj->Type;
+ PccAcpi->Length = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_5_HW_REGISTERS_COMMUNICATIONS);
+ PccAcpi->Version = PccCmObj->Version;
+ PccAcpi->BaseAddress = GenericPccCmObj->BaseAddress;
+ PccAcpi->SharedMemoryRangeLength = GenericPccCmObj->AddressLength;
+
+ CopyMem (
+ &PccAcpi->DoorbellRegister,
+ &Doorbell->Register,
+ sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE)
+ );
+ PccAcpi->DoorbellPreserve = Doorbell->PreserveMask;
+ PccAcpi->DoorbellWrite = Doorbell->WriteMask;
+
+ CopyMem (
+ &PccAcpi->CommandCompleteCheckRegister,
+ &CmdCompleteCheck->Register,
+ sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE)
+ );
+ PccAcpi->CommandCompleteCheckMask = CmdCompleteCheck->PreserveMask;
+ // No Write mask.
+
+ CopyMem (
+ &PccAcpi->ErrorStatusRegister,
+ &ErrorStatus->Register,
+ sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE)
+ );
+ PccAcpi->ErrorStatusMask = ErrorStatus->PreserveMask;
+ // No Write mask.
+
+ PccAcpi->NominalLatency = ChannelTiming->NominalLatency;
+ // No MaximumPeriodicAccessRate.
+ PccAcpi->MinimumRequestTurnaroundTime = ChannelTiming->MinRequestTurnaroundTime;
+
+ return EFI_SUCCESS;
+}
+
+/** Populate the PCCT table using the MappingTable.
+
+ @param [in] MappingTable The mapping table structure.
+ @param [in] Pcc Pointer to an array of Pcc Subpace structures.
+ @param [in] Size Size of the Pcc array.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_BUFFER_TOO_SMALL Buffer too small.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+PopulatePcctTable (
+ IN MAPPING_TABLE *MappingTable,
+ IN VOID *Pcc,
+ IN UINT32 Size
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *PccBuffer;
+ UINT32 CmObjSize;
+ UINT32 Index;
+ UINT32 MaxIndex;
+ VOID **Table;
+ VOID *CurrentPccSubspace;
+
+ ASSERT (MappingTable != NULL);
+ ASSERT (MappingTable->Table != NULL);
+
+ PccBuffer = Pcc;
+ MaxIndex = MappingTable->MaxIndex;
+ Table = MappingTable->Table;
+
+ for (Index = 0; Index < MaxIndex; Index++) {
+ CurrentPccSubspace = Table[Index];
+ if (CurrentPccSubspace == NULL) {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ switch (((PCC_SUBSPACE_GENERIC_INFO *)CurrentPccSubspace)->Type) {
+ case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_GENERIC:
+ Status = AddSubspaceStructType0 (
+ (CM_ARM_PCC_SUBSPACE_TYPE0_INFO *)CurrentPccSubspace,
+ (EFI_ACPI_6_4_PCCT_SUBSPACE_GENERIC *)PccBuffer
+ );
+
+ CmObjSize = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_GENERIC);
+ break;
+
+ case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS:
+ Status = AddSubspaceStructType1 (
+ (CM_ARM_PCC_SUBSPACE_TYPE1_INFO *)CurrentPccSubspace,
+ (EFI_ACPI_6_4_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS *)PccBuffer
+ );
+
+ CmObjSize = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS);
+ break;
+
+ case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS:
+ Status = AddSubspaceStructType2 (
+ (CM_ARM_PCC_SUBSPACE_TYPE2_INFO *)CurrentPccSubspace,
+ (EFI_ACPI_6_4_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS *)PccBuffer
+ );
+
+ CmObjSize = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS);
+ break;
+
+ case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC:
+ Status = AddSubspaceStructType34 (
+ (CM_ARM_PCC_SUBSPACE_TYPE3_INFO *)CurrentPccSubspace,
+ (EFI_ACPI_6_4_PCCT_SUBSPACE_3_EXTENDED_PCC *)PccBuffer
+ );
+
+ CmObjSize = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_3_EXTENDED_PCC);
+ break;
+
+ case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC:
+ Status = AddSubspaceStructType34 (
+ (CM_ARM_PCC_SUBSPACE_TYPE4_INFO *)CurrentPccSubspace,
+ (EFI_ACPI_6_4_PCCT_SUBSPACE_4_EXTENDED_PCC *)PccBuffer
+ );
+
+ CmObjSize = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_4_EXTENDED_PCC);
+ break;
+
+ case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_5_HW_REGISTERS_COMMUNICATIONS:
+ Status = AddSubspaceStructType5 (
+ (CM_ARM_PCC_SUBSPACE_TYPE5_INFO *)CurrentPccSubspace,
+ (EFI_ACPI_6_4_PCCT_SUBSPACE_5_HW_REGISTERS_COMMUNICATIONS *)PccBuffer
+ );
+
+ CmObjSize = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_5_HW_REGISTERS_COMMUNICATIONS);
+ break;
+
+ default:
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ } // switch
+
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ if (Size < CmObjSize) {
+ ASSERT_EFI_ERROR (EFI_BUFFER_TOO_SMALL);
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ PccBuffer += CmObjSize;
+ Size -= CmObjSize;
+ } // for
+
+ return EFI_SUCCESS;
+}
+
+/** Construct the PCCT ACPI table.
+
+ Called by the Dynamic Table Manager, this function invokes the
+ Configuration Manager protocol interface to get the required hardware
+ information for generating the ACPI table.
+
+ If this function allocates any resources then they must be freed
+ in the FreeXXXXTableResources function.
+
+ @param [in] This Pointer to the table generator.
+ @param [in] AcpiTableInfo Pointer to the ACPI Table Info.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [out] Table Pointer to the constructed ACPI Table.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for the
+ requested object.
+ @retval EFI_BUFFER_TOO_SMALL Buffer too small.
+ @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+BuildPcctTable (
+ IN CONST ACPI_TABLE_GENERATOR *CONST This,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table
+ )
+{
+ EFI_STATUS Status;
+ ACPI_PCCT_GENERATOR *Generator;
+ UINT32 TableSize;
+ EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER *Pcct;
+ UINT8 *Buffer;
+
+ MAPPING_TABLE *MappingTable;
+ UINT32 MappingTableCount;
+
+ CM_ARM_PCC_SUBSPACE_TYPE0_INFO *PccType0;
+ UINT32 PccType0Count;
+ CM_ARM_PCC_SUBSPACE_TYPE1_INFO *PccType1;
+ UINT32 PccType1Count;
+ CM_ARM_PCC_SUBSPACE_TYPE2_INFO *PccType2;
+ UINT32 PccType2Count;
+ CM_ARM_PCC_SUBSPACE_TYPE3_INFO *PccType3;
+ UINT32 PccType3Count;
+ CM_ARM_PCC_SUBSPACE_TYPE4_INFO *PccType4;
+ UINT32 PccType4Count;
+ CM_ARM_PCC_SUBSPACE_TYPE5_INFO *PccType5;
+ UINT32 PccType5Count;
+
+ ASSERT (This != NULL);
+ ASSERT (AcpiTableInfo != NULL);
+ ASSERT (CfgMgrProtocol != NULL);
+ ASSERT (Table != NULL);
+ ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID);
+ ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature);
+
+ if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) ||
+ (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision))
+ {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: PCCT: Requested table revision = %d, is not supported."
+ "Supported table revision: Minimum = %d, Maximum = %d\n",
+ AcpiTableInfo->AcpiTableRevision,
+ This->MinAcpiTableRevision,
+ This->AcpiTableRevision
+ ));
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Generator = (ACPI_PCCT_GENERATOR *)This;
+ MappingTable = &Generator->MappingTable;
+ *Table = NULL;
+
+ // First get all the Pcc Subpace CmObj of type X.
+
+ Status = GetEArmObjPccSubspaceType0Info (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &PccType0,
+ &PccType0Count
+ );
+ if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = GetEArmObjPccSubspaceType1Info (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &PccType1,
+ &PccType1Count
+ );
+ if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = GetEArmObjPccSubspaceType2Info (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &PccType2,
+ &PccType2Count
+ );
+ if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = GetEArmObjPccSubspaceType3Info (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &PccType3,
+ &PccType3Count
+ );
+ if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = GetEArmObjPccSubspaceType4Info (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &PccType4,
+ &PccType4Count
+ );
+ if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = GetEArmObjPccSubspaceType5Info (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &PccType5,
+ &PccType5Count
+ );
+ if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ // Count the number of Pcc Subspaces.
+ MappingTableCount = PccType0Count;
+ MappingTableCount += PccType1Count;
+ MappingTableCount += PccType2Count;
+ MappingTableCount += PccType3Count;
+ MappingTableCount += PccType4Count;
+ MappingTableCount += PccType5Count;
+
+ Status = MappingTableInitialize (MappingTable, MappingTableCount);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ // Map the Subspace Ids for all types.
+
+ Status = MapPccSubspaceId (MappingTable, PccType0, PccType0Count);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = MapPccSubspaceId (MappingTable, PccType1, PccType1Count);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = MapPccSubspaceId (MappingTable, PccType2, PccType2Count);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = MapPccSubspaceId (MappingTable, PccType3, PccType3Count);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = MapPccSubspaceId (MappingTable, PccType4, PccType4Count);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = MapPccSubspaceId (MappingTable, PccType5, PccType5Count);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ // Compute the size of the PCCT table.
+ TableSize = sizeof (EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER);
+ TableSize += PccType0Count * sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_GENERIC);
+ TableSize += PccType1Count * sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS);
+ TableSize += PccType2Count * sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS);
+ TableSize += PccType3Count * sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_3_EXTENDED_PCC);
+ TableSize += PccType4Count * sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_4_EXTENDED_PCC);
+ TableSize += PccType5Count * sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_5_HW_REGISTERS_COMMUNICATIONS);
+
+ // Allocate a Buffer for the PCCT table.
+ *Table = (EFI_ACPI_DESCRIPTION_HEADER *)AllocateZeroPool (TableSize);
+ if (*Table == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Pcct = (EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER *)*Table;
+
+ Status = AddAcpiHeader (
+ CfgMgrProtocol,
+ This,
+ &Pcct->Header,
+ AcpiTableInfo,
+ TableSize
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: PCCT: Failed to add ACPI header. Status = %r\n",
+ Status
+ ));
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Buffer = (UINT8 *)Pcct;
+ Buffer += sizeof (EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER);
+ TableSize -= sizeof (EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER);
+
+ // Populate the PCCT table by following the Subspace Id mapping.
+ Status = PopulatePcctTable (MappingTable, Buffer, TableSize);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ // Setup the Reserved fields once mHasPlatformInterrupt hase been populated.
+ Pcct->Flags = mHasPlatformInterrupt;
+ Pcct->Reserved = EFI_ACPI_RESERVED_QWORD;
+
+ MappingTableFree (MappingTable);
+
+ return Status;
+
+error_handler:
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: PCCT: Failed to install table. Status = %r\n",
+ Status
+ ));
+
+ if (*Table != NULL) {
+ FreePool (*Table);
+ *Table = NULL;
+ }
+
+ MappingTableFree (MappingTable);
+
+ return Status;
+}
+
+/** Free any resources allocated for constructing the PCCT.
+
+ @param [in] This Pointer to the table generator.
+ @param [in] AcpiTableInfo Pointer to the ACPI Table Info.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in, out] Table Pointer to the ACPI Table.
+
+ @retval EFI_SUCCESS The resources were freed successfully.
+ @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid.
+**/
+STATIC
+EFI_STATUS
+FreePcctTableResources (
+ IN CONST ACPI_TABLE_GENERATOR *CONST This,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table
+ )
+{
+ ASSERT (This != NULL);
+ ASSERT (AcpiTableInfo != NULL);
+ ASSERT (CfgMgrProtocol != NULL);
+ ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID);
+ ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature);
+
+ if ((Table == NULL) || (*Table == NULL)) {
+ DEBUG ((DEBUG_ERROR, "ERROR: PCCT: Invalid Table Pointer\n"));
+ ASSERT ((Table != NULL) && (*Table != NULL));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FreePool (*Table);
+ *Table = NULL;
+ return EFI_SUCCESS;
+}
+
+/** This macro defines the PCCT Table Generator revision.
+*/
+#define PCCT_GENERATOR_REVISION CREATE_REVISION (1, 0)
+
+/** The interface for the PCCT Table Generator.
+*/
+STATIC
+ACPI_PCCT_GENERATOR PcctGenerator = {
+ // ACPI table generator header
+ {
+ // Generator ID
+ CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdPcct),
+ // Generator Description
+ L"ACPI.STD.PCCT.GENERATOR",
+ // ACPI Table Signature
+ EFI_ACPI_6_4_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE,
+ // ACPI Table Revision supported by this Generator
+ EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL_TABLE_REVISION,
+ // Minimum ACPI Table Revision supported by this Generator
+ EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL_TABLE_REVISION,
+ // Creator ID
+ TABLE_GENERATOR_CREATOR_ID_ARM,
+ // Creator Revision
+ PCCT_GENERATOR_REVISION,
+ // Build Table function
+ BuildPcctTable,
+ // Free Resource function
+ FreePcctTableResources,
+ // Extended build function not needed
+ NULL,
+ // Extended build function not implemented by the generator.
+ // Hence extended free resource function is not required.
+ NULL
+ },
+
+ // Private fields are defined from here.
+
+ // Mapping Table
+ {
+ // Table
+ NULL,
+ // MaxIndex
+ 0,
+ },
+};
+
+/** Register the Generator with the ACPI Table Factory.
+
+ @param [in] ImageHandle The handle to the image.
+ @param [in] SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS The Generator is registered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_ALREADY_STARTED The Generator for the Table ID
+ is already registered.
+**/
+EFI_STATUS
+EFIAPI
+AcpiPcctLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = RegisterAcpiTableGenerator (&PcctGenerator.Header);
+ DEBUG ((DEBUG_INFO, "PCCT: Register Generator. Status = %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
+
+/** Deregister the Generator from the ACPI Table Factory.
+
+ @param [in] ImageHandle The handle to the image.
+ @param [in] SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS The Generator is deregistered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The Generator is not registered.
+**/
+EFI_STATUS
+EFIAPI
+AcpiPcctLibDestructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = DeregisterAcpiTableGenerator (&PcctGenerator.Header);
+ DEBUG ((DEBUG_INFO, "PCCT: Deregister Generator. Status = %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.h b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.h
new file mode 100644
index 000000000000..0631a1f5b74b
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiPcctLibArm/PcctGenerator.h
@@ -0,0 +1,43 @@
+/** @file
+ PCCT Table Generator
+
+ Copyright (c) 2022, Arm Limited. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - ACPI 6.4 Specification - January 2021
+ s14 PLATFORM COMMUNICATIONS CHANNEL (PCC)
+
+**/
+
+#ifndef PCCT_GENERATOR_H_
+#define PCCT_GENERATOR_H_
+
+#pragma pack(1)
+
+/** Structure used to map a Pcc Subspace to an index.
+*/
+typedef struct MappingTable {
+ /// Mapping table for Subspace Ids.
+ /// Subspace ID/Index <-> CM_ARM_PCC_SUBSPACE_TYPE[X]_INFO pointer
+ VOID **Table;
+
+ /// Number of entries in the Table.
+ UINT32 MaxIndex;
+} MAPPING_TABLE;
+
+/** A structure holding the Pcct generator and additional private data.
+*/
+typedef struct AcpiPcctGenerator {
+ /// ACPI Table generator header
+ ACPI_TABLE_GENERATOR Header;
+
+ // Private fields are defined from here.
+
+ /// Table to map: Subspace ID/Index <-> CM_ARM_PCC_SUBSPACE_TYPE[X]_INFO pointer
+ MAPPING_TABLE MappingTable;
+} ACPI_PCCT_GENERATOR;
+
+#pragma pack()
+
+#endif // PCCT_GENERATOR_H_
diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
index 21d1f3f08b16..4d7aa7963fae 100644
--- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
+++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
[SAMI] The changes in ConfigurationManagerObjectParser.c should be in
the previous patch 10/14. Otherise it would break git bisect.
If you agree, I will move the changes in
ConfigurationManagerObjectParser.c in patch 10/14 before merging.
[/SAMI]

@@ -539,7 +539,7 @@ STATIC CONST CM_OBJ_PARSER CmArmCpcInfoParser[] = {
{ "NominalFrequencyInteger", 4, "0x%lx", NULL },
};
-/** A parser for the CM_ARM_MAILBOX_REGISTER_INFO struct.
+/** A parser for the PCC_MAILBOX_REGISTER_INFO struct.
*/
STATIC CONST CM_OBJ_PARSER CmArmMailboxRegisterInfoParser[] = {
{ "Register", sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE), NULL, NULL,
@@ -548,7 +548,7 @@ STATIC CONST CM_OBJ_PARSER CmArmMailboxRegisterInfoParser[] = {
{ "WriteMask", 8, "0x%llx", NULL },
};
-/** A parser for the CM_ARM_PCC_SUBSPACE_CHANNEL_TIMING_INFO struct.
+/** A parser for the PCC_SUBSPACE_CHANNEL_TIMING_INFO struct.
*/
STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceChannelTimingInfoParser[] = {
{ "NominalLatency", 4, "0x%x", NULL },
@@ -559,14 +559,14 @@ STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceChannelTimingInfoParser[] = {
/** A parser for EArmObjPccSubspaceType0Info.
*/
STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType0InfoParser[] = {
- { "SubspaceId", 1, "0x%x", NULL },
- { "Type", 1, "0x%x", NULL },
- { "BaseAddress", 8, "0x%llx", NULL },
- { "AddressLength", 8, "0x%llx", NULL },
- { "DoorbellReg", sizeof (CM_ARM_MAILBOX_REGISTER_INFO),
+ { "SubspaceId", 1, "0x%x", NULL },
+ { "Type", 1, "0x%x", NULL },
+ { "BaseAddress", 8, "0x%llx", NULL },
+ { "AddressLength", 8, "0x%llx", NULL },
+ { "DoorbellReg", sizeof (PCC_MAILBOX_REGISTER_INFO),
NULL, NULL, CmArmMailboxRegisterInfoParser,
ARRAY_SIZE (CmArmMailboxRegisterInfoParser) },
- { "DoorbellReg", sizeof (CM_ARM_PCC_SUBSPACE_CHANNEL_TIMING_INFO),
+ { "DoorbellReg", sizeof (PCC_SUBSPACE_CHANNEL_TIMING_INFO),
NULL, NULL, CmArmPccSubspaceChannelTimingInfoParser,
ARRAY_SIZE (CmArmPccSubspaceChannelTimingInfoParser) },
};
@@ -574,7 +574,7 @@ STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType0InfoParser[] = {
/** A parser for EArmObjPccSubspaceType1Info.
*/
STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType1InfoParser[] = {
- { "GenericPccInfo", sizeof (CM_ARM_PCC_SUBSPACE_GENERIC_INFO),
+ { "GenericPccInfo", sizeof (PCC_SUBSPACE_GENERIC_INFO),
NULL, NULL, CmArmPccSubspaceType0InfoParser,
ARRAY_SIZE (CmArmPccSubspaceType0InfoParser) },
{ "PlatIrq", sizeof (CM_ARM_GENERIC_INTERRUPT),
@@ -585,12 +585,12 @@ STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType1InfoParser[] = {
/** A parser for EArmObjPccSubspaceType2Info.
*/
STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType2InfoParser[] = {
- { "GenericPccInfo", sizeof (CM_ARM_PCC_SUBSPACE_GENERIC_INFO),
+ { "GenericPccInfo", sizeof (PCC_SUBSPACE_GENERIC_INFO),
NULL, NULL, CmArmPccSubspaceType0InfoParser,
ARRAY_SIZE (CmArmPccSubspaceType0InfoParser) },
- { "PlatIrq", sizeof (CM_ARM_GENERIC_INTERRUPT), NULL,NULL,
+ { "PlatIrq", sizeof (CM_ARM_GENERIC_INTERRUPT), NULL,NULL,
CmArmGenericInterruptParser, ARRAY_SIZE (CmArmGenericInterruptParser) },
- { "PlatIrqAckReg", sizeof (CM_ARM_MAILBOX_REGISTER_INFO),
+ { "PlatIrqAckReg", sizeof (PCC_MAILBOX_REGISTER_INFO),
NULL, NULL, CmArmMailboxRegisterInfoParser,
ARRAY_SIZE (CmArmMailboxRegisterInfoParser) },
};
@@ -598,21 +598,21 @@ STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType2InfoParser[] = {
/** A parser for EArmObjPccSubspaceType3Info or EArmObjPccSubspaceType4Info.
*/
STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType34InfoParser[] = {
- { "GenericPccInfo", sizeof (CM_ARM_PCC_SUBSPACE_GENERIC_INFO),
+ { "GenericPccInfo", sizeof (PCC_SUBSPACE_GENERIC_INFO),
NULL, NULL, CmArmPccSubspaceType0InfoParser,
ARRAY_SIZE (CmArmPccSubspaceType0InfoParser) },
- { "PlatIrq", sizeof (CM_ARM_GENERIC_INTERRUPT), NULL,NULL,
+ { "PlatIrq", sizeof (CM_ARM_GENERIC_INTERRUPT), NULL,NULL,
CmArmGenericInterruptParser, ARRAY_SIZE (CmArmGenericInterruptParser) },
- { "PlatIrqAckReg", sizeof (CM_ARM_MAILBOX_REGISTER_INFO),
+ { "PlatIrqAckReg", sizeof (PCC_MAILBOX_REGISTER_INFO),
NULL, NULL, CmArmMailboxRegisterInfoParser,
ARRAY_SIZE (CmArmMailboxRegisterInfoParser) },
- { "CmdCompleteCheckReg", sizeof (CM_ARM_MAILBOX_REGISTER_INFO),
+ { "CmdCompleteCheckReg", sizeof (PCC_MAILBOX_REGISTER_INFO),
NULL, NULL, CmArmMailboxRegisterInfoParser,
ARRAY_SIZE (CmArmMailboxRegisterInfoParser) },
- { "CmdCompleteUpdateReg", sizeof (CM_ARM_MAILBOX_REGISTER_INFO),
+ { "CmdCompleteUpdateReg", sizeof (PCC_MAILBOX_REGISTER_INFO),
NULL, NULL, CmArmMailboxRegisterInfoParser,
ARRAY_SIZE (CmArmMailboxRegisterInfoParser) },
- { "ErrorStatusReg", sizeof (CM_ARM_MAILBOX_REGISTER_INFO),
+ { "ErrorStatusReg", sizeof (PCC_MAILBOX_REGISTER_INFO),
NULL, NULL, CmArmMailboxRegisterInfoParser,
ARRAY_SIZE (CmArmMailboxRegisterInfoParser) },
};
@@ -620,16 +620,16 @@ STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType34InfoParser[] = {
/** A parser for EArmObjPccSubspaceType5Info.
*/
STATIC CONST CM_OBJ_PARSER CmArmPccSubspaceType5InfoParser[] = {
- { "GenericPccInfo", sizeof (CM_ARM_PCC_SUBSPACE_GENERIC_INFO),
+ { "GenericPccInfo", sizeof (PCC_SUBSPACE_GENERIC_INFO),
NULL, NULL, CmArmPccSubspaceType0InfoParser,
ARRAY_SIZE (CmArmPccSubspaceType0InfoParser) },
- { "Version", 2, "0x%x",NULL },
- { "PlatIrq", sizeof (CM_ARM_GENERIC_INTERRUPT), NULL, NULL,
+ { "Version", 2, "0x%x",NULL },
+ { "PlatIrq", sizeof (CM_ARM_GENERIC_INTERRUPT), NULL, NULL,
CmArmGenericInterruptParser, ARRAY_SIZE (CmArmGenericInterruptParser) },
- { "CmdCompleteCheckReg", sizeof (CM_ARM_MAILBOX_REGISTER_INFO),
+ { "CmdCompleteCheckReg", sizeof (PCC_MAILBOX_REGISTER_INFO),
NULL, NULL, CmArmMailboxRegisterInfoParser,
ARRAY_SIZE (CmArmMailboxRegisterInfoParser) },
- { "ErrorStatusReg", sizeof (CM_ARM_MAILBOX_REGISTER_INFO),
+ { "ErrorStatusReg", sizeof (PCC_MAILBOX_REGISTER_INFO),
NULL, NULL, CmArmMailboxRegisterInfoParser,
ARRAY_SIZE (CmArmMailboxRegisterInfoParser) },
};


Re: [PATCH 1/2] UefiCpuPkg/SmmCpuFeaturesLib: Abstract arch dependent code

Ni, Ray
 

Can you do rename SmmCpuFeaturesLibCommon.c to IntelSmmCpuFeaturesLib.c?
This helps to keep the change history because I see that almost all content from Common.c is moved to Intelxxx.c.

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Chang,
Abner via groups.io
Sent: Friday, September 30, 2022 5:52 PM
To: devel@edk2.groups.io
Cc: Abdul Lateef Attar <abdattar@...>; Garrett Kirkendall
<garrett.kirkendall@...>; Paul Grimes <paul.grimes@...>; Dong,
Eric <eric.dong@...>; Ni, Ray <ray.ni@...>; Kumar, Rahul R
<rahul.r.kumar@...>
Subject: [edk2-devel] [PATCH 1/2] UefiCpuPkg/SmmCpuFeaturesLib:
Abstract arch dependent code

From: Abner Chang <abner.chang@...>

This change strips away Intel X86 implementation and put
it in the IntelSmmCpuFeatureLib

Signed-off-by: Abner Chang <abner.chang@...>
Cc: Abdul Lateef Attar <abdattar@...>
Cc: Garrett Kirkendall <garrett.kirkendall@...>
Cc: Paul Grimes <paul.grimes@...>
Cc: Eric Dong <eric.dong@...>
Cc: Ray Ni <ray.ni@...>
Cc: Rahul Kumar <rahul1.kumar@...>
---
.../SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf | 1 +
.../SmmCpuFeaturesLibStm.inf | 1 +
.../StandaloneMmCpuFeaturesLib.inf | 1 +
.../SmmCpuFeaturesLib/CpuFeaturesLib.h | 6 +
.../IntelSmmCpuFeaturesLib.c | 403 ++++++++++++++++++
.../SmmCpuFeaturesLibCommon.c | 391 +----------------
6 files changed, 413 insertions(+), 390 deletions(-)
create mode 100644
UefiCpuPkg/Library/SmmCpuFeaturesLib/IntelSmmCpuFeaturesLib.c

diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
index 7b5cef97008..9ac7dde78f8 100644
--- a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
+++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
@@ -18,6 +18,7 @@

[Sources]
CpuFeaturesLib.h
+ IntelSmmCpuFeaturesLib.c
SmmCpuFeaturesLib.c
SmmCpuFeaturesLibCommon.c
SmmCpuFeaturesLibNoStm.c
diff --git
a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf
b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf
index 85214ee31cd..86d367e0a09 100644
--- a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf
+++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf
@@ -19,6 +19,7 @@

[Sources]
CpuFeaturesLib.h
+ IntelSmmCpuFeaturesLib.c
SmmCpuFeaturesLibCommon.c
SmmStm.c
SmmStm.h
diff --git
a/UefiCpuPkg/Library/SmmCpuFeaturesLib/StandaloneMmCpuFeaturesLib.i
nf
b/UefiCpuPkg/Library/SmmCpuFeaturesLib/StandaloneMmCpuFeaturesLib.i
nf
index 3eacab48db3..61890205e18 100644
---
a/UefiCpuPkg/Library/SmmCpuFeaturesLib/StandaloneMmCpuFeaturesLib.i
nf
+++
b/UefiCpuPkg/Library/SmmCpuFeaturesLib/StandaloneMmCpuFeaturesLib.i
nf
@@ -20,6 +20,7 @@

[Sources]
CpuFeaturesLib.h
+ IntelSmmCpuFeaturesLib.c
StandaloneMmCpuFeaturesLib.c
SmmCpuFeaturesLibCommon.c
SmmCpuFeaturesLibNoStm.c
diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/CpuFeaturesLib.h
b/UefiCpuPkg/Library/SmmCpuFeaturesLib/CpuFeaturesLib.h
index 8a1c2adc5c4..fd3e902547c 100644
--- a/UefiCpuPkg/Library/SmmCpuFeaturesLib/CpuFeaturesLib.h
+++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/CpuFeaturesLib.h
@@ -9,6 +9,12 @@
#ifndef CPU_FEATURES_LIB_H_
#define CPU_FEATURES_LIB_H_

+#include <Library/SmmCpuFeaturesLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+
/**
Performs library initialization.

diff --git
a/UefiCpuPkg/Library/SmmCpuFeaturesLib/IntelSmmCpuFeaturesLib.c
b/UefiCpuPkg/Library/SmmCpuFeaturesLib/IntelSmmCpuFeaturesLib.c
new file mode 100644
index 00000000000..cb4897b21e3
--- /dev/null
+++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/IntelSmmCpuFeaturesLib.c
@@ -0,0 +1,403 @@
+/** @file
+Implementation shared across all library instances.
+
+Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.<BR>
+Copyright (c) Microsoft Corporation.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CpuFeaturesLib.h"
+
+#include <Library/MtrrLib.h>
+#include <Register/Intel/Cpuid.h>
+#include <Register/Intel/SmramSaveStateMap.h>
+
+//
+// Machine Specific Registers (MSRs)
+//
+#define SMM_FEATURES_LIB_IA32_MTRR_CAP 0x0FE
+#define SMM_FEATURES_LIB_IA32_FEATURE_CONTROL 0x03A
+#define SMM_FEATURES_LIB_IA32_SMRR_PHYSBASE 0x1F2
+#define SMM_FEATURES_LIB_IA32_SMRR_PHYSMASK 0x1F3
+#define SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE 0x0A0
+#define SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSMASK 0x0A1
+#define EFI_MSR_SMRR_MASK 0xFFFFF000
+#define EFI_MSR_SMRR_PHYS_MASK_VALID BIT11
+#define SMM_FEATURES_LIB_SMM_FEATURE_CONTROL 0x4E0
+
+//
+// MSRs required for configuration of SMM Code Access Check
+//
+#define SMM_FEATURES_LIB_IA32_MCA_CAP 0x17D
+#define SMM_CODE_ACCESS_CHK_BIT BIT58
+
+//
+// Set default value to assume IA-32 Architectural MSRs are used
+//
+UINT32 mSmrrPhysBaseMsr =
SMM_FEATURES_LIB_IA32_SMRR_PHYSBASE;
+UINT32 mSmrrPhysMaskMsr =
SMM_FEATURES_LIB_IA32_SMRR_PHYSMASK;
+
+//
+// Set default value to assume MTRRs need to be configured on each SMI
+//
+BOOLEAN mNeedConfigureMtrrs = TRUE;
+
+//
+// Array for state of SMRR enable on all CPUs
+//
+BOOLEAN *mSmrrEnabled;
+
+/**
+ Performs library initialization.
+
+ This initialization function contains common functionality shared betwen all
+ library instance constructors.
+
+**/
+VOID
+CpuFeaturesLibInitialization (
+ VOID
+ )
+{
+ UINT32 RegEax;
+ UINT32 RegEdx;
+ UINTN FamilyId;
+ UINTN ModelId;
+
+ //
+ // Retrieve CPU Family and Model
+ //
+ AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, &RegEdx);
+ FamilyId = (RegEax >> 8) & 0xf;
+ ModelId = (RegEax >> 4) & 0xf;
+ if ((FamilyId == 0x06) || (FamilyId == 0x0f)) {
+ ModelId = ModelId | ((RegEax >> 12) & 0xf0);
+ }
+
+ //
+ // Check CPUID(CPUID_VERSION_INFO).EDX[12] for MTRR capability
+ //
+ if ((RegEdx & BIT12) != 0) {
+ //
+ // Check MTRR_CAP MSR bit 11 for SMRR support
+ //
+ if ((AsmReadMsr64 (SMM_FEATURES_LIB_IA32_MTRR_CAP) & BIT11) !=
0) {
+ ASSERT (FeaturePcdGet (PcdSmrrEnable));
+ }
+ }
+
+ //
+ // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
+ // Volume 3C, Section 35.3 MSRs in the Intel(R) Atom(TM) Processor
Family
+ //
+ // If CPU Family/Model is 06_1CH, 06_26H, 06_27H, 06_35H or 06_36H,
then
+ // SMRR Physical Base and SMM Physical Mask MSRs are not available.
+ //
+ if (FamilyId == 0x06) {
+ if ((ModelId == 0x1C) || (ModelId == 0x26) || (ModelId == 0x27) ||
(ModelId == 0x35) || (ModelId == 0x36)) {
+ ASSERT (!FeaturePcdGet (PcdSmrrEnable));
+ }
+ }
+
+ //
+ // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
+ // Volume 3C, Section 35.2 MSRs in the Intel(R) Core(TM) 2 Processor
Family
+ //
+ // If CPU Family/Model is 06_0F or 06_17, then use Intel(R) Core(TM) 2
+ // Processor Family MSRs
+ //
+ if (FamilyId == 0x06) {
+ if ((ModelId == 0x17) || (ModelId == 0x0f)) {
+ mSmrrPhysBaseMsr =
SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE;
+ mSmrrPhysMaskMsr =
SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSMASK;
+ }
+ }
+
+ //
+ // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
+ // Volume 3C, Section 34.4.2 SMRAM Caching
+ // An IA-32 processor does not automatically write back and invalidate its
+ // caches before entering SMM or before exiting SMM. Because of this
behavior,
+ // care must be taken in the placement of the SMRAM in system memory
and in
+ // the caching of the SMRAM to prevent cache incoherence when
switching back
+ // and forth between SMM and protected mode operation.
+ //
+ // An IA-32 processor is a processor that does not support the Intel 64
+ // Architecture. Support for the Intel 64 Architecture can be detected
from
+ // CPUID(CPUID_EXTENDED_CPU_SIG).EDX[29]
+ //
+ // If an IA-32 processor is detected, then set mNeedConfigureMtrrs to
TRUE,
+ // so caches are flushed on SMI entry and SMI exit, the interrupted code
+ // MTRRs are saved/restored, and MTRRs for SMM are loaded.
+ //
+ AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
+ if (RegEax >= CPUID_EXTENDED_CPU_SIG) {
+ AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx);
+ if ((RegEdx & BIT29) != 0) {
+ mNeedConfigureMtrrs = FALSE;
+ }
+ }
+
+ //
+ // Allocate array for state of SMRR enable on all CPUs
+ //
+ mSmrrEnabled = (BOOLEAN *)AllocatePool (sizeof (BOOLEAN) *
GetCpuMaxLogicalProcessorNumber ());
+ ASSERT (mSmrrEnabled != NULL);
+}
+
+/**
+ Called during the very first SMI into System Management Mode to initialize
+ CPU features, including SMBASE, for the currently executing CPU. Since
this
+ is the first SMI, the SMRAM Save State Map is at the default address of
+ SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET. The
currently executing
+ CPU is specified by CpuIndex and CpuIndex can be used to access
information
+ about the currently executing CPU in the ProcessorInfo array and the
+ HotPlugCpuData data structure.
+
+ @param[in] CpuIndex The index of the CPU to initialize. The value
+ must be between 0 and the NumberOfCpus field in
+ the System Management System Table (SMST).
+ @param[in] IsMonarch TRUE if the CpuIndex is the index of the CPU
that
+ was elected as monarch during System Management
+ Mode initialization.
+ FALSE if the CpuIndex is not the index of the CPU
+ that was elected as monarch during System
+ Management Mode initialization.
+ @param[in] ProcessorInfo Pointer to an array of
EFI_PROCESSOR_INFORMATION
+ structures. ProcessorInfo[CpuIndex] contains the
+ information for the currently executing CPU.
+ @param[in] CpuHotPlugData Pointer to the CPU_HOT_PLUG_DATA
structure that
+ contains the ApidId and SmBase arrays.
+**/
+VOID
+EFIAPI
+SmmCpuFeaturesInitializeProcessor (
+ IN UINTN CpuIndex,
+ IN BOOLEAN IsMonarch,
+ IN EFI_PROCESSOR_INFORMATION *ProcessorInfo,
+ IN CPU_HOT_PLUG_DATA *CpuHotPlugData
+ )
+{
+ SMRAM_SAVE_STATE_MAP *CpuState;
+ UINT64 FeatureControl;
+ UINT32 RegEax;
+ UINT32 RegEdx;
+ UINTN FamilyId;
+ UINTN ModelId;
+
+ //
+ // Configure SMBASE.
+ //
+ CpuState = (SMRAM_SAVE_STATE_MAP
*)(UINTN)(SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET);
+ CpuState->x86.SMBASE = (UINT32)CpuHotPlugData->SmBase[CpuIndex];
+
+ //
+ // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
+ // Volume 3C, Section 35.2 MSRs in the Intel(R) Core(TM) 2 Processor
Family
+ //
+ // If Intel(R) Core(TM) Core(TM) 2 Processor Family MSRs are being used,
then
+ // make sure SMRR Enable(BIT3) of MSR_FEATURE_CONTROL MSR(0x3A)
is set before
+ // accessing SMRR base/mask MSRs. If Lock(BIT0) of
MSR_FEATURE_CONTROL MSR(0x3A)
+ // is set, then the MSR is locked and can not be modified.
+ //
+ if ((FeaturePcdGet (PcdSmrrEnable)) && (mSmrrPhysBaseMsr ==
SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE)) {
+ FeatureControl = AsmReadMsr64
(SMM_FEATURES_LIB_IA32_FEATURE_CONTROL);
+ if ((FeatureControl & BIT3) == 0) {
+ ASSERT ((FeatureControl & BIT0) == 0);
+ if ((FeatureControl & BIT0) == 0) {
+ AsmWriteMsr64 (SMM_FEATURES_LIB_IA32_FEATURE_CONTROL,
FeatureControl | BIT3);
+ }
+ }
+ }
+
+ //
+ // If SMRR is supported, then program SMRR base/mask MSRs.
+ // The EFI_MSR_SMRR_PHYS_MASK_VALID bit is not set until the first
normal SMI.
+ // The code that initializes SMM environment is running in normal mode
+ // from SMRAM region. If SMRR is enabled here, then the SMRAM region
+ // is protected and the normal mode code execution will fail.
+ //
+ if (FeaturePcdGet (PcdSmrrEnable)) {
+ //
+ // SMRR size cannot be less than 4-KBytes
+ // SMRR size must be of length 2^n
+ // SMRR base alignment cannot be less than SMRR length
+ //
+ if ((CpuHotPlugData->SmrrSize < SIZE_4KB) ||
+ (CpuHotPlugData->SmrrSize != GetPowerOfTwo32 (CpuHotPlugData-
SmrrSize)) ||
+ ((CpuHotPlugData->SmrrBase & ~(CpuHotPlugData->SmrrSize - 1)) !=
CpuHotPlugData->SmrrBase))
+ {
+ //
+ // Print message and halt if CPU is Monarch
+ //
+ if (IsMonarch) {
+ DEBUG ((DEBUG_ERROR, "SMM Base/Size does not meet
alignment/size requirement!\n"));
+ CpuDeadLoop ();
+ }
+ } else {
+ AsmWriteMsr64 (mSmrrPhysBaseMsr, CpuHotPlugData->SmrrBase |
MTRR_CACHE_WRITE_BACK);
+ AsmWriteMsr64 (mSmrrPhysMaskMsr, (~(CpuHotPlugData->SmrrSize - 1)
& EFI_MSR_SMRR_MASK));
+ mSmrrEnabled[CpuIndex] = FALSE;
+ }
+ }
+
+ //
+ // Retrieve CPU Family and Model
+ //
+ AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, &RegEdx);
+ FamilyId = (RegEax >> 8) & 0xf;
+ ModelId = (RegEax >> 4) & 0xf;
+ if ((FamilyId == 0x06) || (FamilyId == 0x0f)) {
+ ModelId = ModelId | ((RegEax >> 12) & 0xf0);
+ }
+
+ //
+ // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
+ // Volume 3C, Section 35.10.1 MSRs in 4th Generation Intel(R) Core(TM)
+ // Processor Family.
+ //
+ // If CPU Family/Model is 06_3C, 06_45, or 06_46 then use 4th Generation
+ // Intel(R) Core(TM) Processor Family MSRs.
+ //
+ if (FamilyId == 0x06) {
+ if ((ModelId == 0x3C) || (ModelId == 0x45) || (ModelId == 0x46) ||
+ (ModelId == 0x3D) || (ModelId == 0x47) || (ModelId == 0x4E) ||
(ModelId == 0x4F) ||
+ (ModelId == 0x3F) || (ModelId == 0x56) || (ModelId == 0x57) ||
(ModelId == 0x5C) ||
+ (ModelId == 0x8C))
+ {
+ //
+ // Check to see if the CPU supports the SMM Code Access Check feature
+ // Do not access this MSR unless the CPU supports the
SmmRegFeatureControl
+ //
+ if ((AsmReadMsr64 (SMM_FEATURES_LIB_IA32_MCA_CAP) &
SMM_CODE_ACCESS_CHK_BIT) != 0) {
+ ASSERT (FeaturePcdGet (PcdSmmFeatureControlEnable));
+ }
+ }
+ }
+
+ //
+ // Call internal worker function that completes the CPU initialization
+ //
+ FinishSmmCpuFeaturesInitializeProcessor ();
+}
+
+/**
+ Determines if MTRR registers must be configured to set SMRAM cache-
ability
+ when executing in System Management Mode.
+
+ @retval TRUE MTRR registers must be configured to set SMRAM cache-
ability.
+ @retval FALSE MTRR registers do not need to be configured to set
SMRAM
+ cache-ability.
+**/
+BOOLEAN
+EFIAPI
+SmmCpuFeaturesNeedConfigureMtrrs (
+ VOID
+ )
+{
+ return mNeedConfigureMtrrs;
+}
+
+/**
+ Disable SMRR register if SMRR is supported and
SmmCpuFeaturesNeedConfigureMtrrs()
+ returns TRUE.
+**/
+VOID
+EFIAPI
+SmmCpuFeaturesDisableSmrr (
+ VOID
+ )
+{
+ if (FeaturePcdGet (PcdSmrrEnable) && mNeedConfigureMtrrs) {
+ AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64
(mSmrrPhysMaskMsr) & ~EFI_MSR_SMRR_PHYS_MASK_VALID);
+ }
+}
+
+/**
+ Enable SMRR register if SMRR is supported and
SmmCpuFeaturesNeedConfigureMtrrs()
+ returns TRUE.
+**/
+VOID
+EFIAPI
+SmmCpuFeaturesReenableSmrr (
+ VOID
+ )
+{
+ if (FeaturePcdGet (PcdSmrrEnable) && mNeedConfigureMtrrs) {
+ AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64
(mSmrrPhysMaskMsr) | EFI_MSR_SMRR_PHYS_MASK_VALID);
+ }
+}
+
+/**
+ Processor specific hook point each time a CPU enters System Management
Mode.
+
+ @param[in] CpuIndex The index of the CPU that has entered SMM. The
value
+ must be between 0 and the NumberOfCpus field in the
+ System Management System Table (SMST).
+**/
+VOID
+EFIAPI
+SmmCpuFeaturesRendezvousEntry (
+ IN UINTN CpuIndex
+ )
+{
+ //
+ // If SMRR is supported and this is the first normal SMI, then enable SMRR
+ //
+ if (FeaturePcdGet (PcdSmrrEnable) && !mSmrrEnabled[CpuIndex]) {
+ AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64
(mSmrrPhysMaskMsr) | EFI_MSR_SMRR_PHYS_MASK_VALID);
+ mSmrrEnabled[CpuIndex] = TRUE;
+ }
+}
+
+/**
+ Returns the current value of the SMM register for the specified CPU.
+ If the SMM register is not supported, then 0 is returned.
+
+ @param[in] CpuIndex The index of the CPU to read the SMM register.
The
+ value must be between 0 and the NumberOfCpus field in
+ the System Management System Table (SMST).
+ @param[in] RegName Identifies the SMM register to read.
+
+ @return The value of the SMM register specified by RegName from the
CPU
+ specified by CpuIndex.
+**/
+UINT64
+EFIAPI
+SmmCpuFeaturesGetSmmRegister (
+ IN UINTN CpuIndex,
+ IN SMM_REG_NAME RegName
+ )
+{
+ if (FeaturePcdGet (PcdSmmFeatureControlEnable) && (RegName ==
SmmRegFeatureControl)) {
+ return AsmReadMsr64
(SMM_FEATURES_LIB_SMM_FEATURE_CONTROL);
+ }
+
+ return 0;
+}
+
+/**
+ Sets the value of an SMM register on a specified CPU.
+ If the SMM register is not supported, then no action is performed.
+
+ @param[in] CpuIndex The index of the CPU to write the SMM register.
The
+ value must be between 0 and the NumberOfCpus field in
+ the System Management System Table (SMST).
+ @param[in] RegName Identifies the SMM register to write.
+ registers are read-only.
+ @param[in] Value The value to write to the SMM register.
+**/
+VOID
+EFIAPI
+SmmCpuFeaturesSetSmmRegister (
+ IN UINTN CpuIndex,
+ IN SMM_REG_NAME RegName,
+ IN UINT64 Value
+ )
+{
+ if (FeaturePcdGet (PcdSmmFeatureControlEnable) && (RegName ==
SmmRegFeatureControl)) {
+ AsmWriteMsr64 (SMM_FEATURES_LIB_SMM_FEATURE_CONTROL,
Value);
+ }
+}
+
diff --git
a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibCommon.c
b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibCommon.c
index 75a0ec8e948..7777e52740e 100644
---
a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibCommon.c
+++
b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibCommon.c
@@ -14,278 +14,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/PcdLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DebugLib.h>
-#include <Register/Intel/Cpuid.h>
-#include <Register/Intel/SmramSaveStateMap.h>
-#include "CpuFeaturesLib.h"
-
-//
-// Machine Specific Registers (MSRs)
-//
-#define SMM_FEATURES_LIB_IA32_MTRR_CAP 0x0FE
-#define SMM_FEATURES_LIB_IA32_FEATURE_CONTROL 0x03A
-#define SMM_FEATURES_LIB_IA32_SMRR_PHYSBASE 0x1F2
-#define SMM_FEATURES_LIB_IA32_SMRR_PHYSMASK 0x1F3
-#define SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE 0x0A0
-#define SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSMASK 0x0A1
-#define EFI_MSR_SMRR_MASK 0xFFFFF000
-#define EFI_MSR_SMRR_PHYS_MASK_VALID BIT11
-#define SMM_FEATURES_LIB_SMM_FEATURE_CONTROL 0x4E0
-
-//
-// MSRs required for configuration of SMM Code Access Check
-//
-#define SMM_FEATURES_LIB_IA32_MCA_CAP 0x17D
-#define SMM_CODE_ACCESS_CHK_BIT BIT58
-
-//
-// Set default value to assume IA-32 Architectural MSRs are used
-//
-UINT32 mSmrrPhysBaseMsr =
SMM_FEATURES_LIB_IA32_SMRR_PHYSBASE;
-UINT32 mSmrrPhysMaskMsr =
SMM_FEATURES_LIB_IA32_SMRR_PHYSMASK;
-
-//
-// Set default value to assume MTRRs need to be configured on each SMI
-//
-BOOLEAN mNeedConfigureMtrrs = TRUE;
-
-//
-// Array for state of SMRR enable on all CPUs
-//
-BOOLEAN *mSmrrEnabled;
-
-/**
- Performs library initialization.
-
- This initialization function contains common functionality shared betwen all
- library instance constructors.
-
-**/
-VOID
-CpuFeaturesLibInitialization (
- VOID
- )
-{
- UINT32 RegEax;
- UINT32 RegEdx;
- UINTN FamilyId;
- UINTN ModelId;
-
- //
- // Retrieve CPU Family and Model
- //
- AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, &RegEdx);
- FamilyId = (RegEax >> 8) & 0xf;
- ModelId = (RegEax >> 4) & 0xf;
- if ((FamilyId == 0x06) || (FamilyId == 0x0f)) {
- ModelId = ModelId | ((RegEax >> 12) & 0xf0);
- }
-
- //
- // Check CPUID(CPUID_VERSION_INFO).EDX[12] for MTRR capability
- //
- if ((RegEdx & BIT12) != 0) {
- //
- // Check MTRR_CAP MSR bit 11 for SMRR support
- //
- if ((AsmReadMsr64 (SMM_FEATURES_LIB_IA32_MTRR_CAP) & BIT11) != 0)
{
- ASSERT (FeaturePcdGet (PcdSmrrEnable));
- }
- }
-
- //
- // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
- // Volume 3C, Section 35.3 MSRs in the Intel(R) Atom(TM) Processor Family
- //
- // If CPU Family/Model is 06_1CH, 06_26H, 06_27H, 06_35H or 06_36H, then
- // SMRR Physical Base and SMM Physical Mask MSRs are not available.
- //
- if (FamilyId == 0x06) {
- if ((ModelId == 0x1C) || (ModelId == 0x26) || (ModelId == 0x27) ||
(ModelId == 0x35) || (ModelId == 0x36)) {
- ASSERT (!FeaturePcdGet (PcdSmrrEnable));
- }
- }
-
- //
- // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
- // Volume 3C, Section 35.2 MSRs in the Intel(R) Core(TM) 2 Processor
Family
- //
- // If CPU Family/Model is 06_0F or 06_17, then use Intel(R) Core(TM) 2
- // Processor Family MSRs
- //
- if (FamilyId == 0x06) {
- if ((ModelId == 0x17) || (ModelId == 0x0f)) {
- mSmrrPhysBaseMsr =
SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE;
- mSmrrPhysMaskMsr =
SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSMASK;
- }
- }
-
- //
- // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
- // Volume 3C, Section 34.4.2 SMRAM Caching
- // An IA-32 processor does not automatically write back and invalidate its
- // caches before entering SMM or before exiting SMM. Because of this
behavior,
- // care must be taken in the placement of the SMRAM in system memory
and in
- // the caching of the SMRAM to prevent cache incoherence when
switching back
- // and forth between SMM and protected mode operation.
- //
- // An IA-32 processor is a processor that does not support the Intel 64
- // Architecture. Support for the Intel 64 Architecture can be detected from
- // CPUID(CPUID_EXTENDED_CPU_SIG).EDX[29]
- //
- // If an IA-32 processor is detected, then set mNeedConfigureMtrrs to
TRUE,
- // so caches are flushed on SMI entry and SMI exit, the interrupted code
- // MTRRs are saved/restored, and MTRRs for SMM are loaded.
- //
- AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
- if (RegEax >= CPUID_EXTENDED_CPU_SIG) {
- AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx);
- if ((RegEdx & BIT29) != 0) {
- mNeedConfigureMtrrs = FALSE;
- }
- }
-
- //
- // Allocate array for state of SMRR enable on all CPUs
- //
- mSmrrEnabled = (BOOLEAN *)AllocatePool (sizeof (BOOLEAN) *
GetCpuMaxLogicalProcessorNumber ());
- ASSERT (mSmrrEnabled != NULL);
-}
-
-/**
- Called during the very first SMI into System Management Mode to initialize
- CPU features, including SMBASE, for the currently executing CPU. Since
this
- is the first SMI, the SMRAM Save State Map is at the default address of
- SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET. The
currently executing
- CPU is specified by CpuIndex and CpuIndex can be used to access
information
- about the currently executing CPU in the ProcessorInfo array and the
- HotPlugCpuData data structure.
-
- @param[in] CpuIndex The index of the CPU to initialize. The value
- must be between 0 and the NumberOfCpus field in
- the System Management System Table (SMST).
- @param[in] IsMonarch TRUE if the CpuIndex is the index of the CPU
that
- was elected as monarch during System Management
- Mode initialization.
- FALSE if the CpuIndex is not the index of the CPU
- that was elected as monarch during System
- Management Mode initialization.
- @param[in] ProcessorInfo Pointer to an array of
EFI_PROCESSOR_INFORMATION
- structures. ProcessorInfo[CpuIndex] contains the
- information for the currently executing CPU.
- @param[in] CpuHotPlugData Pointer to the CPU_HOT_PLUG_DATA
structure that
- contains the ApidId and SmBase arrays.
-**/
-VOID
-EFIAPI
-SmmCpuFeaturesInitializeProcessor (
- IN UINTN CpuIndex,
- IN BOOLEAN IsMonarch,
- IN EFI_PROCESSOR_INFORMATION *ProcessorInfo,
- IN CPU_HOT_PLUG_DATA *CpuHotPlugData
- )
-{
- SMRAM_SAVE_STATE_MAP *CpuState;
- UINT64 FeatureControl;
- UINT32 RegEax;
- UINT32 RegEdx;
- UINTN FamilyId;
- UINTN ModelId;
-
- //
- // Configure SMBASE.
- //
- CpuState = (SMRAM_SAVE_STATE_MAP
*)(UINTN)(SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET);
- CpuState->x86.SMBASE = (UINT32)CpuHotPlugData->SmBase[CpuIndex];
-
- //
- // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
- // Volume 3C, Section 35.2 MSRs in the Intel(R) Core(TM) 2 Processor
Family
- //
- // If Intel(R) Core(TM) Core(TM) 2 Processor Family MSRs are being used,
then
- // make sure SMRR Enable(BIT3) of MSR_FEATURE_CONTROL MSR(0x3A) is
set before
- // accessing SMRR base/mask MSRs. If Lock(BIT0) of
MSR_FEATURE_CONTROL MSR(0x3A)
- // is set, then the MSR is locked and can not be modified.
- //
- if ((FeaturePcdGet (PcdSmrrEnable)) && (mSmrrPhysBaseMsr ==
SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE)) {
- FeatureControl = AsmReadMsr64
(SMM_FEATURES_LIB_IA32_FEATURE_CONTROL);
- if ((FeatureControl & BIT3) == 0) {
- ASSERT ((FeatureControl & BIT0) == 0);
- if ((FeatureControl & BIT0) == 0) {
- AsmWriteMsr64 (SMM_FEATURES_LIB_IA32_FEATURE_CONTROL,
FeatureControl | BIT3);
- }
- }
- }

- //
- // If SMRR is supported, then program SMRR base/mask MSRs.
- // The EFI_MSR_SMRR_PHYS_MASK_VALID bit is not set until the first
normal SMI.
- // The code that initializes SMM environment is running in normal mode
- // from SMRAM region. If SMRR is enabled here, then the SMRAM region
- // is protected and the normal mode code execution will fail.
- //
- if (FeaturePcdGet (PcdSmrrEnable)) {
- //
- // SMRR size cannot be less than 4-KBytes
- // SMRR size must be of length 2^n
- // SMRR base alignment cannot be less than SMRR length
- //
- if ((CpuHotPlugData->SmrrSize < SIZE_4KB) ||
- (CpuHotPlugData->SmrrSize != GetPowerOfTwo32 (CpuHotPlugData-
SmrrSize)) ||
- ((CpuHotPlugData->SmrrBase & ~(CpuHotPlugData->SmrrSize - 1)) !=
CpuHotPlugData->SmrrBase))
- {
- //
- // Print message and halt if CPU is Monarch
- //
- if (IsMonarch) {
- DEBUG ((DEBUG_ERROR, "SMM Base/Size does not meet
alignment/size requirement!\n"));
- CpuDeadLoop ();
- }
- } else {
- AsmWriteMsr64 (mSmrrPhysBaseMsr, CpuHotPlugData->SmrrBase |
MTRR_CACHE_WRITE_BACK);
- AsmWriteMsr64 (mSmrrPhysMaskMsr, (~(CpuHotPlugData->SmrrSize - 1)
& EFI_MSR_SMRR_MASK));
- mSmrrEnabled[CpuIndex] = FALSE;
- }
- }
-
- //
- // Retrieve CPU Family and Model
- //
- AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, &RegEdx);
- FamilyId = (RegEax >> 8) & 0xf;
- ModelId = (RegEax >> 4) & 0xf;
- if ((FamilyId == 0x06) || (FamilyId == 0x0f)) {
- ModelId = ModelId | ((RegEax >> 12) & 0xf0);
- }
-
- //
- // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
- // Volume 3C, Section 35.10.1 MSRs in 4th Generation Intel(R) Core(TM)
- // Processor Family.
- //
- // If CPU Family/Model is 06_3C, 06_45, or 06_46 then use 4th Generation
- // Intel(R) Core(TM) Processor Family MSRs.
- //
- if (FamilyId == 0x06) {
- if ((ModelId == 0x3C) || (ModelId == 0x45) || (ModelId == 0x46) ||
- (ModelId == 0x3D) || (ModelId == 0x47) || (ModelId == 0x4E) ||
(ModelId == 0x4F) ||
- (ModelId == 0x3F) || (ModelId == 0x56) || (ModelId == 0x57) ||
(ModelId == 0x5C) ||
- (ModelId == 0x8C))
- {
- //
- // Check to see if the CPU supports the SMM Code Access Check feature
- // Do not access this MSR unless the CPU supports the
SmmRegFeatureControl
- //
- if ((AsmReadMsr64 (SMM_FEATURES_LIB_IA32_MCA_CAP) &
SMM_CODE_ACCESS_CHK_BIT) != 0) {
- ASSERT (FeaturePcdGet (PcdSmmFeatureControlEnable));
- }
- }
- }
-
- //
- // Call internal worker function that completes the CPU initialization
- //
- FinishSmmCpuFeaturesInitializeProcessor ();
-}
+#include "CpuFeaturesLib.h"

/**
This function updates the SMRAM save state on the currently executing
CPU
@@ -345,75 +75,6 @@ SmmCpuFeaturesSmmRelocationComplete (
{
}

-/**
- Determines if MTRR registers must be configured to set SMRAM cache-
ability
- when executing in System Management Mode.
-
- @retval TRUE MTRR registers must be configured to set SMRAM cache-
ability.
- @retval FALSE MTRR registers do not need to be configured to set SMRAM
- cache-ability.
-**/
-BOOLEAN
-EFIAPI
-SmmCpuFeaturesNeedConfigureMtrrs (
- VOID
- )
-{
- return mNeedConfigureMtrrs;
-}
-
-/**
- Disable SMRR register if SMRR is supported and
SmmCpuFeaturesNeedConfigureMtrrs()
- returns TRUE.
-**/
-VOID
-EFIAPI
-SmmCpuFeaturesDisableSmrr (
- VOID
- )
-{
- if (FeaturePcdGet (PcdSmrrEnable) && mNeedConfigureMtrrs) {
- AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64
(mSmrrPhysMaskMsr) & ~EFI_MSR_SMRR_PHYS_MASK_VALID);
- }
-}
-
-/**
- Enable SMRR register if SMRR is supported and
SmmCpuFeaturesNeedConfigureMtrrs()
- returns TRUE.
-**/
-VOID
-EFIAPI
-SmmCpuFeaturesReenableSmrr (
- VOID
- )
-{
- if (FeaturePcdGet (PcdSmrrEnable) && mNeedConfigureMtrrs) {
- AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64
(mSmrrPhysMaskMsr) | EFI_MSR_SMRR_PHYS_MASK_VALID);
- }
-}
-
-/**
- Processor specific hook point each time a CPU enters System Management
Mode.
-
- @param[in] CpuIndex The index of the CPU that has entered SMM. The
value
- must be between 0 and the NumberOfCpus field in the
- System Management System Table (SMST).
-**/
-VOID
-EFIAPI
-SmmCpuFeaturesRendezvousEntry (
- IN UINTN CpuIndex
- )
-{
- //
- // If SMRR is supported and this is the first normal SMI, then enable SMRR
- //
- if (FeaturePcdGet (PcdSmrrEnable) && !mSmrrEnabled[CpuIndex]) {
- AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64
(mSmrrPhysMaskMsr) | EFI_MSR_SMRR_PHYS_MASK_VALID);
- mSmrrEnabled[CpuIndex] = TRUE;
- }
-}
-
/**
Processor specific hook point each time a CPU exits System Management
Mode.

@@ -456,56 +117,6 @@ SmmCpuFeaturesIsSmmRegisterSupported (
return FALSE;
}

-/**
- Returns the current value of the SMM register for the specified CPU.
- If the SMM register is not supported, then 0 is returned.
-
- @param[in] CpuIndex The index of the CPU to read the SMM register.
The
- value must be between 0 and the NumberOfCpus field in
- the System Management System Table (SMST).
- @param[in] RegName Identifies the SMM register to read.
-
- @return The value of the SMM register specified by RegName from the
CPU
- specified by CpuIndex.
-**/
-UINT64
-EFIAPI
-SmmCpuFeaturesGetSmmRegister (
- IN UINTN CpuIndex,
- IN SMM_REG_NAME RegName
- )
-{
- if (FeaturePcdGet (PcdSmmFeatureControlEnable) && (RegName ==
SmmRegFeatureControl)) {
- return AsmReadMsr64 (SMM_FEATURES_LIB_SMM_FEATURE_CONTROL);
- }
-
- return 0;
-}
-
-/**
- Sets the value of an SMM register on a specified CPU.
- If the SMM register is not supported, then no action is performed.
-
- @param[in] CpuIndex The index of the CPU to write the SMM register.
The
- value must be between 0 and the NumberOfCpus field in
- the System Management System Table (SMST).
- @param[in] RegName Identifies the SMM register to write.
- registers are read-only.
- @param[in] Value The value to write to the SMM register.
-**/
-VOID
-EFIAPI
-SmmCpuFeaturesSetSmmRegister (
- IN UINTN CpuIndex,
- IN SMM_REG_NAME RegName,
- IN UINT64 Value
- )
-{
- if (FeaturePcdGet (PcdSmmFeatureControlEnable) && (RegName ==
SmmRegFeatureControl)) {
- AsmWriteMsr64 (SMM_FEATURES_LIB_SMM_FEATURE_CONTROL,
Value);
- }
-}
-
/**
Read an SMM Save State register on the target processor. If this function
returns EFI_UNSUPPORTED, then the caller is responsible for reading the
--
2.37.1.windows.1





Re: [PATCH 1/1] ArmPlatformPkg: Remove AP support from PrePi/PrePeiCore

Leif Lindholm
 

On Thu, Oct 27, 2022 at 20:10:33 +0200, Ard Biesheuvel wrote:
On Thu, 27 Oct 2022 at 19:31, Rebecca Cran <quic_rcran@...> wrote:

Modern platforms use TF-A, so there's no need for support of
secondary cores in EDK2 since TF-A will keep them in a holding
pen until the PSCI_CPU_ON SMC call is received.

Therefore, remove the code that handles secondary CPUs from
PrePeiCore and PrePi and add ASSERTs if a secondary core
reaches the functions.

Signed-off-by: Rebecca Cran <rebecca@...>
No objections to this patch, but this change will break the old SMP
32-bit ARM platforms in edk2-platforms so you will need to propose a
solution for those as well.
I think TC2 is the last one of those standing. And I don't see much
value in keeping all of this around for such a niche (and old)
platform. If someone ports TF-A to it, we could always add it back in
later.

Single-core non-PSCI platforms (i.e. beagleboard) aren't affected.

Sami: would you be OK with deleting the TC2 support in edk2-platforms?

/
Leif

---
ArmPlatformPkg/PrePeiCore/MainMPCore.c | 92 --------------------
ArmPlatformPkg/PrePeiCore/MainUniCore.c | 9 --
ArmPlatformPkg/PrePeiCore/PrePeiCore.c | 37 ++++----
ArmPlatformPkg/PrePi/MainMPCore.c | 69 ---------------
ArmPlatformPkg/PrePi/MainUniCore.c | 9 --
ArmPlatformPkg/PrePi/PrePi.c | 36 ++++----
6 files changed, 34 insertions(+), 218 deletions(-)

diff --git a/ArmPlatformPkg/PrePeiCore/MainMPCore.c b/ArmPlatformPkg/PrePeiCore/MainMPCore.c
index b5d0d3a6442f..44850a4f3946 100644
--- a/ArmPlatformPkg/PrePeiCore/MainMPCore.c
+++ b/ArmPlatformPkg/PrePeiCore/MainMPCore.c
@@ -12,98 +12,6 @@

#include "PrePeiCore.h"

-/*
- * This is the main function for secondary cores. They loop around until a non Null value is written to
- * SYS_FLAGS register.The SYS_FLAGS register is platform specific.
- * Note:The secondary cores, while executing secondary_main, assumes that:
- * : SGI 0 is configured as Non-secure interrupt
- * : Priority Mask is configured to allow SGI 0
- * : Interrupt Distributor and CPU interfaces are enabled
- *
- */
-VOID
-EFIAPI
-SecondaryMain (
- IN UINTN MpId
- )
-{
- EFI_STATUS Status;
- UINTN PpiListSize;
- UINTN PpiListCount;
- EFI_PEI_PPI_DESCRIPTOR *PpiList;
- ARM_MP_CORE_INFO_PPI *ArmMpCoreInfoPpi;
- UINTN Index;
- UINTN ArmCoreCount;
- ARM_CORE_INFO *ArmCoreInfoTable;
- UINT32 ClusterId;
- UINT32 CoreId;
-
- VOID (*SecondaryStart)(
- VOID
- );
- UINTN SecondaryEntryAddr;
- UINTN AcknowledgeInterrupt;
- UINTN InterruptId;
-
- ClusterId = GET_CLUSTER_ID (MpId);
- CoreId = GET_CORE_ID (MpId);
-
- // Get the gArmMpCoreInfoPpiGuid
- PpiListSize = 0;
- ArmPlatformGetPlatformPpiList (&PpiListSize, &PpiList);
- PpiListCount = PpiListSize / sizeof (EFI_PEI_PPI_DESCRIPTOR);
- for (Index = 0; Index < PpiListCount; Index++, PpiList++) {
- if (CompareGuid (PpiList->Guid, &gArmMpCoreInfoPpiGuid) == TRUE) {
- break;
- }
- }
-
- // On MP Core Platform we must implement the ARM MP Core Info PPI
- ASSERT (Index != PpiListCount);
-
- ArmMpCoreInfoPpi = PpiList->Ppi;
- ArmCoreCount = 0;
- Status = ArmMpCoreInfoPpi->GetMpCoreInfo (&ArmCoreCount, &ArmCoreInfoTable);
- ASSERT_EFI_ERROR (Status);
-
- // Find the core in the ArmCoreTable
- for (Index = 0; Index < ArmCoreCount; Index++) {
- if ((GET_MPIDR_AFF1 (ArmCoreInfoTable[Index].Mpidr) == ClusterId) &&
- (GET_MPIDR_AFF0 (ArmCoreInfoTable[Index].Mpidr) == CoreId))
- {
- break;
- }
- }
-
- // The ARM Core Info Table must define every core
- ASSERT (Index != ArmCoreCount);
-
- // Clear Secondary cores MailBox
- MmioWrite32 (ArmCoreInfoTable[Index].MailboxClearAddress, ArmCoreInfoTable[Index].MailboxClearValue);
-
- do {
- ArmCallWFI ();
-
- // Read the Mailbox
- SecondaryEntryAddr = MmioRead32 (ArmCoreInfoTable[Index].MailboxGetAddress);
-
- // Acknowledge the interrupt and send End of Interrupt signal.
- AcknowledgeInterrupt = ArmGicAcknowledgeInterrupt (PcdGet64 (PcdGicInterruptInterfaceBase), &InterruptId);
- // Check if it is a valid interrupt ID
- if (InterruptId < ArmGicGetMaxNumInterrupts (PcdGet64 (PcdGicDistributorBase))) {
- // Got a valid SGI number hence signal End of Interrupt
- ArmGicEndOfInterrupt (PcdGet64 (PcdGicInterruptInterfaceBase), AcknowledgeInterrupt);
- }
- } while (SecondaryEntryAddr == 0);
-
- // Jump to secondary core entry point.
- SecondaryStart = (VOID (*)()) SecondaryEntryAddr;
- SecondaryStart ();
-
- // The secondaries shouldn't reach here
- ASSERT (FALSE);
-}
-
VOID
EFIAPI
PrimaryMain (
diff --git a/ArmPlatformPkg/PrePeiCore/MainUniCore.c b/ArmPlatformPkg/PrePeiCore/MainUniCore.c
index 1c2580eb923b..3d3c6caaa32a 100644
--- a/ArmPlatformPkg/PrePeiCore/MainUniCore.c
+++ b/ArmPlatformPkg/PrePeiCore/MainUniCore.c
@@ -8,15 +8,6 @@

#include "PrePeiCore.h"

-VOID
-EFIAPI
-SecondaryMain (
- IN UINTN MpId
- )
-{
- ASSERT (FALSE);
-}
-
VOID
EFIAPI
PrimaryMain (
diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCore.c b/ArmPlatformPkg/PrePeiCore/PrePeiCore.c
index 42a7ccc9c6a0..64d1ef601ea3 100644
--- a/ArmPlatformPkg/PrePeiCore/PrePeiCore.c
+++ b/ArmPlatformPkg/PrePeiCore/PrePeiCore.c
@@ -117,27 +117,26 @@ CEntryPoint (

// Note: The MMU will be enabled by MemoryPeim. Only the primary core will have the MMU on.

- // If not primary Jump to Secondary Main
- if (ArmPlatformIsPrimaryCore (MpId)) {
- // Invoke "ProcessLibraryConstructorList" to have all library constructors
- // called.
- ProcessLibraryConstructorList ();
-
- PrintFirmwareVersion ();
-
- // Initialize the Debug Agent for Source Level Debugging
- InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL);
- SaveAndSetDebugTimerInterrupt (TRUE);
-
- // Initialize the platform specific controllers
- ArmPlatformInitialize (MpId);
-
- // Goto primary Main.
- PrimaryMain (PeiCoreEntryPoint);
- } else {
- SecondaryMain (MpId);
+ if (!ArmPlatformIsPrimaryCore (MpId)) {
+ ASSERT (FALSE);
}

+ // Invoke "ProcessLibraryConstructorList" to have all library constructors
+ // called.
+ ProcessLibraryConstructorList ();
+
+ PrintFirmwareVersion ();
+
+ // Initialize the Debug Agent for Source Level Debugging
+ InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL);
+ SaveAndSetDebugTimerInterrupt (TRUE);
+
+ // Initialize the platform specific controllers
+ ArmPlatformInitialize (MpId);
+
+ // Goto primary Main.
+ PrimaryMain (PeiCoreEntryPoint);
+
// PEI Core should always load and never return
ASSERT (FALSE);
}
diff --git a/ArmPlatformPkg/PrePi/MainMPCore.c b/ArmPlatformPkg/PrePi/MainMPCore.c
index 68a7c13298d0..ce7058a2846f 100644
--- a/ArmPlatformPkg/PrePi/MainMPCore.c
+++ b/ArmPlatformPkg/PrePi/MainMPCore.c
@@ -33,72 +33,3 @@ PrimaryMain (
// We must never return
ASSERT (FALSE);
}
-
-VOID
-SecondaryMain (
- IN UINTN MpId
- )
-{
- EFI_STATUS Status;
- ARM_MP_CORE_INFO_PPI *ArmMpCoreInfoPpi;
- UINTN Index;
- UINTN ArmCoreCount;
- ARM_CORE_INFO *ArmCoreInfoTable;
- UINT32 ClusterId;
- UINT32 CoreId;
-
- VOID (*SecondaryStart)(
- VOID
- );
- UINTN SecondaryEntryAddr;
- UINTN AcknowledgeInterrupt;
- UINTN InterruptId;
-
- ClusterId = GET_CLUSTER_ID (MpId);
- CoreId = GET_CORE_ID (MpId);
-
- // On MP Core Platform we must implement the ARM MP Core Info PPI (gArmMpCoreInfoPpiGuid)
- Status = GetPlatformPpi (&gArmMpCoreInfoPpiGuid, (VOID **)&ArmMpCoreInfoPpi);
- ASSERT_EFI_ERROR (Status);
-
- ArmCoreCount = 0;
- Status = ArmMpCoreInfoPpi->GetMpCoreInfo (&ArmCoreCount, &ArmCoreInfoTable);
- ASSERT_EFI_ERROR (Status);
-
- // Find the core in the ArmCoreTable
- for (Index = 0; Index < ArmCoreCount; Index++) {
- if ((GET_MPIDR_AFF1 (ArmCoreInfoTable[Index].Mpidr) == ClusterId) &&
- (GET_MPIDR_AFF0 (ArmCoreInfoTable[Index].Mpidr) == CoreId))
- {
- break;
- }
- }
-
- // The ARM Core Info Table must define every core
- ASSERT (Index != ArmCoreCount);
-
- // Clear Secondary cores MailBox
- MmioWrite32 (ArmCoreInfoTable[Index].MailboxClearAddress, ArmCoreInfoTable[Index].MailboxClearValue);
-
- do {
- ArmCallWFI ();
-
- // Read the Mailbox
- SecondaryEntryAddr = MmioRead32 (ArmCoreInfoTable[Index].MailboxGetAddress);
-
- // Acknowledge the interrupt and send End of Interrupt signal.
- AcknowledgeInterrupt = ArmGicAcknowledgeInterrupt (PcdGet64 (PcdGicInterruptInterfaceBase), &InterruptId);
- // Check if it is a valid interrupt ID
- if (InterruptId < ArmGicGetMaxNumInterrupts (PcdGet64 (PcdGicDistributorBase))) {
- // Got a valid SGI number hence signal End of Interrupt
- ArmGicEndOfInterrupt (PcdGet64 (PcdGicInterruptInterfaceBase), AcknowledgeInterrupt);
- }
- } while (SecondaryEntryAddr == 0);
-
- // Jump to secondary core entry point.
- SecondaryStart = (VOID (*)()) SecondaryEntryAddr;
- SecondaryStart ();
-
- // The secondaries shouldn't reach here
- ASSERT (FALSE);
-}
diff --git a/ArmPlatformPkg/PrePi/MainUniCore.c b/ArmPlatformPkg/PrePi/MainUniCore.c
index 6162d1241f84..7449facacd51 100644
--- a/ArmPlatformPkg/PrePi/MainUniCore.c
+++ b/ArmPlatformPkg/PrePi/MainUniCore.c
@@ -20,12 +20,3 @@ PrimaryMain (
// We must never return
ASSERT (FALSE);
}
-
-VOID
-SecondaryMain (
- IN UINTN MpId
- )
-{
- // We must never get into this function on UniCore system
- ASSERT (FALSE);
-}
diff --git a/ArmPlatformPkg/PrePi/PrePi.c b/ArmPlatformPkg/PrePi/PrePi.c
index 9b127b94a67c..60061b8b6963 100644
--- a/ArmPlatformPkg/PrePi/PrePi.c
+++ b/ArmPlatformPkg/PrePi/PrePi.c
@@ -177,7 +177,11 @@ CEntryPoint (
// Initialize the platform specific controllers
ArmPlatformInitialize (MpId);

- if (ArmPlatformIsPrimaryCore (MpId) && PerformanceMeasurementEnabled ()) {
+ if (!ArmPlatformIsPrimaryCore (MpId)) {
+ ASSERT (FALSE);
+ }
+
+ if (PerformanceMeasurementEnabled ()) {
// Initialize the Timer Library to setup the Timer HW controller
TimerConstructor ();
// We cannot call yet the PerformanceLib because the HOB List has not been initialized
@@ -195,29 +199,21 @@ CEntryPoint (

// Define the Global Variable region when we are not running in XIP
if (!IS_XIP ()) {
- if (ArmPlatformIsPrimaryCore (MpId)) {
- if (ArmIsMpCore ()) {
- // Signal the Global Variable Region is defined (event: ARM_CPU_EVENT_DEFAULT)
- ArmCallSEV ();
- }
- } else {
- // Wait the Primary core has defined the address of the Global Variable region (event: ARM_CPU_EVENT_DEFAULT)
- ArmCallWFE ();
+ if (ArmIsMpCore ()) {
+ // Signal the Global Variable Region is defined (event: ARM_CPU_EVENT_DEFAULT)
+ ArmCallSEV ();
}
}

- // If not primary Jump to Secondary Main
- if (ArmPlatformIsPrimaryCore (MpId)) {
- InvalidateDataCacheRange (
- (VOID *)UefiMemoryBase,
- FixedPcdGet32 (PcdSystemMemoryUefiRegionSize)
- );
+ InvalidateDataCacheRange (
+ (VOID *)UefiMemoryBase,
+ FixedPcdGet32 (PcdSystemMemoryUefiRegionSize)
+ );

- // Goto primary Main.
- PrimaryMain (UefiMemoryBase, StacksBase, StartTimeStamp);
- } else {
- SecondaryMain (MpId);
- }
+ PrePiMain (UefiMemoryBase, StacksBase, StartTimeStamp);
+
+ // We must never return
+ ASSERT (FALSE);

// DXE Core should always load and never return
ASSERT (FALSE);
--
2.30.2






Re: [Patch V2] UefiCpuPkg: Restore HpetTimer after CpuExceptionHandlerLib test

Ni, Ray
 

Reviewed-by: Ray Ni <ray.ni@...>

-----Original Message-----
From: Tan, Dun <dun.tan@...>
Sent: Friday, October 28, 2022 11:51 AM
To: devel@edk2.groups.io
Cc: Dong, Eric <eric.dong@...>; Ni, Ray <ray.ni@...>; Kumar,
Rahul R <rahul.r.kumar@...>; Kinney, Michael D
<michael.d.kinney@...>
Subject: [Patch V2] UefiCpuPkg: Restore HpetTimer after
CpuExceptionHandlerLib test

Disable/Restore HpetTimer before and after running the Dxe
CpuExceptionHandlerLib unit test module. During the UnitTest, a
new Idt is initialized for the test. There is no handler for timer
intrrupt in this new idt. After the test module, HpetTimer does
not work any more since the comparator value register and main
counter value register for timer does not match. To fix this issue,
disable/restore HpetTimer before and after Unit Test if HpetTimer
driver has been dispatched. We don't need to send Apic Eoi in this
unit test module.When disabling timer, after RaiseTPL(), if there
is a pending timer interrupt, bit64 of Interrupt Request Register
(IRR) will be set to 1 to indicate there is a pending timer
interrupt. After RestoreTPL(), CPU will handle the pending
interrupt in IRR.Then TimerInterruptHandler calls SendApicEoi().

Signed-off-by: Dun Tan <dun.tan@...>
Cc: Eric Dong <eric.dong@...>
Cc: Ray Ni <ray.ni@...>
Cc: Rahul Kumar <rahul1.kumar@...>
Cc: Michael D Kinney <michael.d.kinney@...>
---

UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionHan
dlerLibUnitTest.inf | 1 +

UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionHan
dlerUnitTest.c | 30 +++++++++++++++++++++++++++++-
2 files changed, 30 insertions(+), 1 deletion(-)

diff --git
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionH
andlerLibUnitTest.inf
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionH
andlerLibUnitTest.inf
index e3dbe7b9ab..a904eb2504 100644
---
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionH
andlerLibUnitTest.inf
+++
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionH
andlerLibUnitTest.inf
@@ -53,6 +53,7 @@

[Protocols]
gEfiMpServiceProtocolGuid
+ gEfiTimerArchProtocolGuid

[Depex]
gEfiMpServiceProtocolGuid
diff --git
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionH
andlerUnitTest.c
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionH
andlerUnitTest.c
index 917fc549bf..1cec3ed809 100644
---
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionH
andlerUnitTest.c
+++
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionH
andlerUnitTest.c
@@ -8,6 +8,7 @@

#include "CpuExceptionHandlerTest.h"
#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/Timer.h>

/**
Initialize Bsp Idt with a new Idt table and return the IA32_DESCRIPTOR
buffer.
@@ -162,8 +163,12 @@ CpuExceptionHandlerTestEntry (
{
EFI_STATUS Status;
UNIT_TEST_FRAMEWORK_HANDLE Framework;
+ EFI_TIMER_ARCH_PROTOCOL *TimerArchProtocol;
+ UINT64 TimerPeriod;

- Framework = NULL;
+ Framework = NULL;
+ TimerArchProtocol = NULL;
+ TimerPeriod = 0;

DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_APP_NAME,
UNIT_TEST_APP_VERSION));

@@ -182,11 +187,34 @@ CpuExceptionHandlerTestEntry (
goto EXIT;
}

+ //
+ // If HpetTimer driver has been dispatched, disable HpetTimer before Unit
Test.
+ //
+ gBS->LocateProtocol (&gEfiTimerArchProtocolGuid, NULL, (VOID
**)&TimerArchProtocol);
+ if (TimerArchProtocol != NULL) {
+ Status = TimerArchProtocol->GetTimerPeriod (TimerArchProtocol,
&TimerPeriod);
+ ASSERT_EFI_ERROR (Status);
+ if (TimerPeriod > 0) {
+ DEBUG ((DEBUG_INFO, "HpetTimer has been dispatched. Disable
HpetTimer.\n"));
+ Status = TimerArchProtocol->SetTimerPeriod (TimerArchProtocol, 0);
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+
//
// Execute the tests.
//
Status = RunAllTestSuites (Framework);

+ //
+ // Restore HpetTimer after Unit Test.
+ //
+ if ((TimerArchProtocol != NULL) && (TimerPeriod > 0)) {
+ DEBUG ((DEBUG_INFO, "Restore HpetTimer after
DxeCpuExceptionHandlerLib UnitTest.\n"));
+ Status = TimerArchProtocol->SetTimerPeriod (TimerArchProtocol,
TimerPeriod);
+ ASSERT_EFI_ERROR (Status);
+ }
+
EXIT:
if (Framework) {
FreeUnitTestFramework (Framework);
--
2.31.1.windows.1


Re: [PATCH] BaseTools: Fix build option overrides Pcd Feature Flag issue

Yuwei Chen
 

Cc Mike.

Thanks,
Christine

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Yuwei
Chen
Sent: Tuesday, October 25, 2022 4:51 PM
To: devel@edk2.groups.io
Cc: Feng, Bob C <bob.c.feng@...>; Gao, Liming
<gaoliming@...>
Subject: [edk2-devel] [PATCH] BaseTools: Fix build option overrides Pcd
Feature Flag issue

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4081

INF [Sources] section Feature Flag Expressions do not use override values
from build --pcd option currently.
This patch fix this issue.

Cc: Bob Feng <bob.c.feng@...>
Cc: Liming Gao <gaoliming@...>
Signed-off-by: Yuwei Chen <yuwei.chen@...>
---
edk2basetools/Workspace/InfBuildData.py | 17 +++++++++++++++++
1 file changed, 17 insertions(+)

diff --git a/edk2basetools/Workspace/InfBuildData.py
b/edk2basetools/Workspace/InfBuildData.py
index c97a70e..8631373 100644
--- a/edk2basetools/Workspace/InfBuildData.py
+++ b/edk2basetools/Workspace/InfBuildData.py
@@ -1055,6 +1055,7 @@ def IsBinaryModule(self):
return False
def CheckFeatureFlagPcd(self,Instance):
Pcds = GlobalData.gPlatformFinalPcds.copy()
+ BuildOptionPcds = GlobalData.BuildOptionPcd
if PcdPattern.search(Instance):
PcdTuple = tuple(Instance.split('.')[::-1])
if PcdTuple in self.Pcds:
@@ -1062,6 +1063,14 @@ def CheckFeatureFlagPcd(self,Instance):
EdkLogger.error('build', FORMAT_INVALID,
"\nFeatureFlagPcd must be defined in a [PcdsFeatureFlag]
or [PcdsFixedAtBuild] section of Dsc or Dec file",
File=str(self), ExtraData=Instance)
+ for item in BuildOptionPcds:
+ if self.Pcds[PcdTuple].TokenCName in item:
+ if type(item) == type(()):
+ # ('gEfiCryptoPkgTokenSpaceGuid', 'PcdOpensslEcEnabled', '',
'1', ('build command options', 1)
+ Pcds[Instance] = list(item)[3]
+ elif type(item) == type(''):
+ # gEfiCryptoPkgTokenSpaceGuid.PcdOpensslEcEnabled=1
+ Pcds[Instance] = item.split('=')[1]
if not Instance in Pcds:
Pcds[Instance] = self.Pcds[PcdTuple].DefaultValue
else: #if PcdTuple not in self.Pcds:
@@ -1085,6 +1094,14 @@ def CheckFeatureFlagPcd(self,Instance):
for Name, Guid in self.Pcds:
if self.Pcds[(Name, Guid)].Type == 'FeatureFlag' or self.Pcds[(Name,
Guid)].Type == 'FixedAtBuild':
PcdFullName = '%s.%s' % (Guid, Name);
+ for item in BuildOptionPcds:
+ if Name in item:
+ if type(item) == type(()):
+ # ('gEfiCryptoPkgTokenSpaceGuid', 'PcdOpensslEcEnabled',
'', '1', ('build command options', 1)
+ Pcds[PcdFullName] = list(item)[3]
+ elif type(item) == type(''):
+ # gEfiCryptoPkgTokenSpaceGuid.PcdOpensslEcEnabled=1
+ Pcds[PcdFullName] = item.split('=')[1]
if not PcdFullName in Pcds:
Pcds[PcdFullName] = self.Pcds[(Name, Guid)].DefaultValue
try:
--
2.27.0.windows.1





Re: [PATCH V2 1/1] OvmfPkg/VmgExitLig: HALT on #VE when access to private memory #ve

Yao, Jiewen
 

Reviewed-by: Jiewen Yao <Jiewen.yao@...>

-----Original Message-----
From: Xu, Min M <min.m.xu@...>
Sent: Friday, October 28, 2022 4:24 PM
To: devel@edk2.groups.io
Cc: Xu, Min M <min.m.xu@...>; Aktas, Erdem
<erdemaktas@...>; Gerd Hoffmann <kraxel@...>; James
Bottomley <jejb@...>; Yao, Jiewen <jiewen.yao@...>;
Tom Lendacky <thomas.lendacky@...>
Subject: [PATCH V2 1/1] OvmfPkg/VmgExitLig: HALT on #VE when access to
private memory

From: Min M Xu <min.m.xu@...>

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4125

EPT-violation #VE should be always on shared memory, which means the
shared bit of the GuestPA should be set. But in current #VE Handler
it is not checked. When it occurs, stop TD immediately and log out
the error.

Cc: Erdem Aktas <erdemaktas@...>
Cc: Gerd Hoffmann <kraxel@...>
Cc: James Bottomley <jejb@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Tom Lendacky <thomas.lendacky@...>
Signed-off-by: Min Xu <min.m.xu@...>
---
.../Library/VmgExitLib/VmTdExitVeHandler.c | 40 ++++++++++++++-----
1 file changed, 29 insertions(+), 11 deletions(-)

diff --git a/OvmfPkg/Library/VmgExitLib/VmTdExitVeHandler.c
b/OvmfPkg/Library/VmgExitLib/VmTdExitVeHandler.c
index b73e877c093b..c89268c5d8e8 100644
--- a/OvmfPkg/Library/VmgExitLib/VmTdExitVeHandler.c
+++ b/OvmfPkg/Library/VmgExitLib/VmTdExitVeHandler.c
@@ -300,23 +300,41 @@ MmioExit (
IN TDCALL_VEINFO_RETURN_DATA *Veinfo
)
{
- UINT64 Status;
- UINT32 MmioSize;
- UINT32 RegSize;
- UINT8 OpCode;
- BOOLEAN SeenRex;
- UINT64 *Reg;
- UINT8 *Rip;
- UINT64 Val;
- UINT32 OpSize;
- MODRM ModRm;
- REX Rex;
+ UINT64 Status;
+ UINT32 MmioSize;
+ UINT32 RegSize;
+ UINT8 OpCode;
+ BOOLEAN SeenRex;
+ UINT64 *Reg;
+ UINT8 *Rip;
+ UINT64 Val;
+ UINT32 OpSize;
+ MODRM ModRm;
+ REX Rex;
+ TD_RETURN_DATA TdReturnData;
+ UINT8 Gpaw;
+ UINT64 TdSharedPageMask;

Rip = (UINT8 *)Regs->Rip;
Val = 0;
Rex.Val = 0;
SeenRex = FALSE;

+ Status = TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData);
+ if (Status == TDX_EXIT_REASON_SUCCESS) {
+ Gpaw = (UINT8)(TdReturnData.TdInfo.Gpaw & 0x3f);
+ TdSharedPageMask = 1ULL << (Gpaw - 1);
+ } else {
+ DEBUG ((DEBUG_ERROR, "TDCALL failed with status=%llx\n", Status));
+ return Status;
+ }
+
+ if ((Veinfo->GuestPA & TdSharedPageMask) == 0) {
+ DEBUG ((DEBUG_ERROR, "EPT-violation #VE on private memory is not
allowed!"));
+ TdVmCall (TDVMCALL_HALT, 0, 0, 0, 0, 0);
+ CpuDeadLoop ();
+ }
+
//
// Default to 32bit transfer
//
--
2.29.2.windows.2


[PATCH V2 1/1] OvmfPkg/VmgExitLig: HALT on #VE when access to private memory #ve

Min Xu
 

From: Min M Xu <min.m.xu@...>

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4125

EPT-violation #VE should be always on shared memory, which means the
shared bit of the GuestPA should be set. But in current #VE Handler
it is not checked. When it occurs, stop TD immediately and log out
the error.

Cc: Erdem Aktas <erdemaktas@...>
Cc: Gerd Hoffmann <kraxel@...>
Cc: James Bottomley <jejb@...>
Cc: Jiewen Yao <jiewen.yao@...>
Cc: Tom Lendacky <thomas.lendacky@...>
Signed-off-by: Min Xu <min.m.xu@...>
---
.../Library/VmgExitLib/VmTdExitVeHandler.c | 40 ++++++++++++++-----
1 file changed, 29 insertions(+), 11 deletions(-)

diff --git a/OvmfPkg/Library/VmgExitLib/VmTdExitVeHandler.c b/OvmfPkg/Library/VmgExitLib/VmTdExitVeHandler.c
index b73e877c093b..c89268c5d8e8 100644
--- a/OvmfPkg/Library/VmgExitLib/VmTdExitVeHandler.c
+++ b/OvmfPkg/Library/VmgExitLib/VmTdExitVeHandler.c
@@ -300,23 +300,41 @@ MmioExit (
IN TDCALL_VEINFO_RETURN_DATA *Veinfo
)
{
- UINT64 Status;
- UINT32 MmioSize;
- UINT32 RegSize;
- UINT8 OpCode;
- BOOLEAN SeenRex;
- UINT64 *Reg;
- UINT8 *Rip;
- UINT64 Val;
- UINT32 OpSize;
- MODRM ModRm;
- REX Rex;
+ UINT64 Status;
+ UINT32 MmioSize;
+ UINT32 RegSize;
+ UINT8 OpCode;
+ BOOLEAN SeenRex;
+ UINT64 *Reg;
+ UINT8 *Rip;
+ UINT64 Val;
+ UINT32 OpSize;
+ MODRM ModRm;
+ REX Rex;
+ TD_RETURN_DATA TdReturnData;
+ UINT8 Gpaw;
+ UINT64 TdSharedPageMask;

Rip = (UINT8 *)Regs->Rip;
Val = 0;
Rex.Val = 0;
SeenRex = FALSE;

+ Status = TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData);
+ if (Status == TDX_EXIT_REASON_SUCCESS) {
+ Gpaw = (UINT8)(TdReturnData.TdInfo.Gpaw & 0x3f);
+ TdSharedPageMask = 1ULL << (Gpaw - 1);
+ } else {
+ DEBUG ((DEBUG_ERROR, "TDCALL failed with status=%llx\n", Status));
+ return Status;
+ }
+
+ if ((Veinfo->GuestPA & TdSharedPageMask) == 0) {
+ DEBUG ((DEBUG_ERROR, "EPT-violation #VE on private memory is not allowed!"));
+ TdVmCall (TDVMCALL_HALT, 0, 0, 0, 0, 0);
+ CpuDeadLoop ();
+ }
+
//
// Default to 32bit transfer
//
--
2.29.2.windows.2


Re: 回复: [edk2-devel] 回复: [edk2-devel] 回复: [edk2-devel] [PATCH] [PATCH]MdeModulePkg/Ufs: Coverity scan flags multiple issues in edk2-stable202205 Signed-off-by: sivaparvathic@ami.com

 

Hi mikuback@..., gaoliming@...,michael.d.kinney@..., vasudevans@..., sundaresans@...
 
Created PULL request for Coverity Issue changes.

BugZilla ID: https://bugzilla.tianocore.org/show_bug.cgi?id=3989 

All Checks are Passed.

Thanks,
Sivaparvathi C


Re: 回复: [edk2-devel] 回复: [edk2-devel] [edk2] [PATCH]MdeModulePkg\scsi: Coverity scan flags multiple issues in edk2-stable202205

 

Hi mikuback@..., gaoliming@...,michael.d.kinney@..., vasudevans@..., sundaresans@...
 
Created PULL request for Coverity Issue changes.

BugZilla ID: https://bugzilla.tianocore.org/show_bug.cgi?id=3994

All Checks are Passed.

Thanks,
Sivaparvathi C