Date   

Re: [PATCH] UefiPayloadPkg: Add macro to support selection of CryptoDxe driver

Guo Dong
 

Reviewed-by: Guo Dong <guo.dong@...>

-----Original Message-----
From: Hsieh, PaytonX <paytonx.hsieh@...>
Sent: Friday, July 22, 2022 12:02 AM
To: devel@edk2.groups.io
Cc: Hsieh, PaytonX <paytonx.hsieh@...>; Dong, Guo <guo.dong@...>; Ni, Ray <ray.ni@...>; Lu, James <james.lu@...>; Guo, Gua <gua.guo@...>
Subject: [PATCH] UefiPayloadPkg: Add macro to support selection of CryptoDxe driver

From: PaytonX Hsieh <paytonx.hsieh@...>

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

Add CRYPTO_PROTOCOL_SUPPORT to decide CryptoDxe built into UPL.efi If CRYPTO_PROTOCOL_SUPPORT is true, BIOS will use crypto protocol instead of building OpensslLib into drivers.

Cc: Guo Dong <guo.dong@...>
Cc: Ray Ni <ray.ni@...>
Cc: James Lu <james.lu@...>
Cc: Gua Guo <gua.guo@...>
Signed-off-by: PaytonX Hsieh <paytonx.hsieh@...>
---
UefiPayloadPkg/UefiPayloadPkg.dsc | 10 ++++++++++ UefiPayloadPkg/UefiPayloadPkg.fdf | 2 ++
2 files changed, 12 insertions(+)

diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc
index 5e947526b7..862d440b16 100644
--- a/UefiPayloadPkg/UefiPayloadPkg.dsc
+++ b/UefiPayloadPkg/UefiPayloadPkg.dsc
@@ -39,6 +39,7 @@
DEFINE ATA_ENABLE = TRUE DEFINE SD_ENABLE = TRUE DEFINE PS2_MOUSE_ENABLE = TRUE+ DEFINE CRYPTO_PROTOCOL_SUPPORT = FALSE DEFINE SD_MMC_TIMEOUT = 1000000 #@@ -189,8 +190,13 @@
CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf DxeHobListLib|UefiPayloadPkg/Library/DxeHobListLib/DxeHobListLib.inf+!if $(CRYPTO_PROTOCOL_SUPPORT) == TRUE BaseCryptLib|CryptoPkg/Library/BaseCryptLibOnProtocolPpi/DxeCryptLib.inf TlsLib|CryptoPkg/Library/BaseCryptLibOnProtocolPpi/DxeCryptLib.inf+!else+ BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf+ TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf+!endif IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf@@ -421,6 +427,7 @@
gUefiPayloadPkgTokenSpaceGuid.PcdBootManagerEscape|$(BOOT_MANAGER_ESCAPE) gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1800000 +!if $(CRYPTO_PROTOCOL_SUPPORT) == TRUE gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.HmacSha256.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Md5.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Pkcs.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY@@ -443,6 +450,7 @@
gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Tls.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.TlsSet.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.TlsGet.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY+!endif [PcdsPatchableInModule.X64] gPcAtChipsetPkgTokenSpaceGuid.PcdRtcIndexRegister|$(RTC_INDEX_REGISTER)@@ -764,11 +772,13 @@
# # Misc #+!if $(CRYPTO_PROTOCOL_SUPPORT) == TRUE CryptoPkg/Driver/CryptoDxe.inf { <LibraryClasses> BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf }+!endif #------------------------------ # Build the shelldiff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf
index 5c055e61b3..afdd6447a7 100644
--- a/UefiPayloadPkg/UefiPayloadPkg.fdf
+++ b/UefiPayloadPkg/UefiPayloadPkg.fdf
@@ -99,7 +99,9 @@ INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf +!if $(CRYPTO_PROTOCOL_SUPPORT) == TRUE INF CryptoPkg/Driver/CryptoDxe.inf+!endif !if $(SECURITY_STUB_ENABLE) == TRUE INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf !endif--
2.28.0.windows.1


[PATCH v4] BaseTools/Capsule: Support signtool input subject name to sign capsule file

Lin, Jason1
 

From: Jason1 Lin <jason1.lin@...>

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

Windows-based system using signtool.exe to sign the capsule.
Add the support to using "--subject-name" argument to assign
the subject name used to sign the capsule file.
This argument would pass to signtool.exe as a part of input
argument with "/n" flag.

NOTE: If using signtool.exe to sign capsule at least need to
choose one of "--pfx-file" and "--subject-name"
argument to input the value.

Signed-off-by: Jason1 Lin <jason1.lin@...>
Cc: Bob Feng <bob.c.feng@...>
Cc: Liming Gao <gaoliming@...>
Cc: Yuwei Chen <yuwei.chen@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Dakota Chiang <dakota.chiang@...>
---
BaseTools/Source/Python/Capsule/GenerateCapsule.py | 43 ++++++++++++++++--=
--
1 file changed, 34 insertions(+), 9 deletions(-)

diff --git a/BaseTools/Source/Python/Capsule/GenerateCapsule.py b/BaseTools=
/Source/Python/Capsule/GenerateCapsule.py
index b8039db878..35435946c6 100644
--- a/BaseTools/Source/Python/Capsule/GenerateCapsule.py
+++ b/BaseTools/Source/Python/Capsule/GenerateCapsule.py
@@ -10,7 +10,7 @@
# keep the tool as simple as possible, it has the following limitations:=0D
# * Do not support vendor code bytes in a capsule.=0D
#=0D
-# Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>=0D
+# Copyright (c) 2018 - 2022, Intel Corporation. All rights reserved.<BR>=0D
# SPDX-License-Identifier: BSD-2-Clause-Patent=0D
#=0D
=0D
@@ -38,11 +38,11 @@ from Common.Edk2.Capsule.FmpPayloadHeader import FmpPa=
yloadHeaderClass
# Globals for help information=0D
#=0D
__prog__ =3D 'GenerateCapsule'=0D
-__version__ =3D '0.9'=0D
-__copyright__ =3D 'Copyright (c) 2018, Intel Corporation. All rights res=
erved.'=0D
+__version__ =3D '0.10'=0D
+__copyright__ =3D 'Copyright (c) 2022, Intel Corporation. All rights res=
erved.'=0D
__description__ =3D 'Generate a capsule.\n'=0D
=0D
-def SignPayloadSignTool (Payload, ToolPath, PfxFile, Verbose =3D False):=0D
+def SignPayloadSignTool (Payload, ToolPath, PfxFile, SubjectName, Verbose =
=3D False):=0D
#=0D
# Create a temporary directory=0D
#=0D
@@ -72,7 +72,10 @@ def SignPayloadSignTool (Payload, ToolPath, PfxFile, Ver=
bose =3D False):
Command =3D Command + '"{Path}" '.format (Path =3D os.path.join (ToolP=
ath, 'signtool.exe'))=0D
Command =3D Command + 'sign /fd sha256 /p7ce DetachedSignedData /p7co =
1.2.840.113549.1.7.2 '=0D
Command =3D Command + '/p7 {TempDir} '.format (TempDir =3D TempDirecto=
ryName)=0D
- Command =3D Command + '/f {PfxFile} '.format (PfxFile =3D PfxFile)=0D
+ if PfxFile is not None:=0D
+ Command =3D Command + '/f {PfxFile} '.format (PfxFile =3D PfxFile)=
=0D
+ if SubjectName is not None:=0D
+ Command =3D Command + '/n {SubjectName} '.format (SubjectName =3D =
SubjectName)=0D
Command =3D Command + TempFileName=0D
if Verbose:=0D
print (Command)=0D
@@ -105,7 +108,7 @@ def SignPayloadSignTool (Payload, ToolPath, PfxFile, Ve=
rbose =3D False):
shutil.rmtree (TempDirectoryName)=0D
return Signature=0D
=0D
-def VerifyPayloadSignTool (Payload, CertData, ToolPath, PfxFile, Verbose =
=3D False):=0D
+def VerifyPayloadSignTool (Payload, CertData, ToolPath, PfxFile, SubjectNa=
me, Verbose =3D False):=0D
print ('signtool verify is not supported.')=0D
raise ValueError ('GenerateCapsule: error: signtool verify is not supp=
orted.')=0D
=0D
@@ -249,6 +252,7 @@ if __name__ =3D=3D '__main__':
HardwareInstance =3D ConvertJsonValue (Config, 'Ha=
rdwareInstance', ValidateUnsignedInteger, Required =3D False, Default =3D 0=
)=0D
MonotonicCount =3D ConvertJsonValue (Config, 'Mo=
notonicCount', ValidateUnsignedInteger, Required =3D False, Default =3D 0)=
=0D
SignToolPfxFile =3D ConvertJsonValue (Config, 'Si=
gnToolPfxFile', os.path.expandvars, Required =3D False, Default =3D None, O=
pen =3D True)=0D
+ SignToolSubjectName =3D ConvertJsonValue (Config, 'Si=
gnToolSubjectName', os.path.expandvars, Required =3D False, Default =3D Non=
e, Open =3D True)=0D
OpenSslSignerPrivateCertFile =3D ConvertJsonValue (Config, 'Op=
enSslSignerPrivateCertFile', os.path.expandvars, Required =3D False, Defaul=
t =3D None, Open =3D True)=0D
OpenSslOtherPublicCertFile =3D ConvertJsonValue (Config, 'Op=
enSslOtherPublicCertFile', os.path.expandvars, Required =3D False, Default =
=3D None, Open =3D True)=0D
OpenSslTrustedPublicCertFile =3D ConvertJsonValue (Config, 'Op=
enSslTrustedPublicCertFile', os.path.expandvars, Required =3D False, Defaul=
t =3D None, Open =3D True)=0D
@@ -264,6 +268,7 @@ if __name__ =3D=3D '__main__':
HardwareInstance,=0D
UpdateImageIndex,=0D
SignToolPfxFile,=0D
+ SignToolSubjectName,=0D
OpenSslSignerPrivateCertFile,=
=0D
OpenSslOtherPublicCertFile,=0D
OpenSslTrustedPublicCertFile,=
=0D
@@ -303,6 +308,7 @@ if __name__ =3D=3D '__main__':
UpdateImageIndex =3D ConvertJsonValue (Config, 'Up=
dateImageIndex', ValidateUnsignedInteger, Required =3D False, Default =3D 1=
)=0D
MonotonicCount =3D ConvertJsonValue (Config, 'Mo=
notonicCount', ValidateUnsignedInteger, Required =3D False, Default =3D 0)=
=0D
SignToolPfxFile =3D ConvertJsonValue (Config, 'Si=
gnToolPfxFile', os.path.expandvars, Required =3D False, Default =3D None, O=
pen =3D True)=0D
+ SignToolSubjectName =3D ConvertJsonValue (Config, 'Si=
gnToolSubjectName', os.path.expandvars, Required =3D False, Default =3D Non=
e, Open =3D True)=0D
OpenSslSignerPrivateCertFile =3D ConvertJsonValue (Config, 'Op=
enSslSignerPrivateCertFile', os.path.expandvars, Required =3D False, Defaul=
t =3D None, Open =3D True)=0D
OpenSslOtherPublicCertFile =3D ConvertJsonValue (Config, 'Op=
enSslOtherPublicCertFile', os.path.expandvars, Required =3D False, Default =
=3D None, Open =3D True)=0D
OpenSslTrustedPublicCertFile =3D ConvertJsonValue (Config, 'Op=
enSslTrustedPublicCertFile', os.path.expandvars, Required =3D False, Defaul=
t =3D None, Open =3D True)=0D
@@ -329,6 +335,7 @@ if __name__ =3D=3D '__main__':
HardwareInstance,=0D
UpdateImageIndex,=0D
SignToolPfxFile,=0D
+ SignToolSubjectName,=0D
OpenSslSignerPrivateCertFile,=
=0D
OpenSslOtherPublicCertFile,=0D
OpenSslTrustedPublicCertFile,=
=0D
@@ -348,6 +355,7 @@ if __name__ =3D=3D '__main__':
"HardwareInstance": str(PayloadDescripto=
r.HardwareInstance),=0D
"UpdateImageIndex": str(PayloadDescripto=
r.UpdateImageIndex),=0D
"SignToolPfxFile": str(PayloadDescriptor=
.SignToolPfxFile),=0D
+ "SignToolSubjectName": str(PayloadDescri=
ptor.SignToolSubjectName),=0D
"OpenSslSignerPrivateCertFile": str(Payl=
oadDescriptor.OpenSslSignerPrivateCertFile),=0D
"OpenSslOtherPublicCertFile": str(Payloa=
dDescriptor.OpenSslOtherPublicCertFile),=0D
"OpenSslTrustedPublicCertFile": str(Payl=
oadDescriptor.OpenSslTrustedPublicCertFile),=0D
@@ -363,6 +371,8 @@ if __name__ =3D=3D '__main__':
for PayloadField in PayloadSection:=0D
if PayloadJsonDescriptorList[Index].SignToolPfxFile is None:=0D
del PayloadField ['SignToolPfxFile']=0D
+ if PayloadJsonDescriptorList[Index].SignToolSubjectName is Non=
e:=0D
+ del PayloadField ['SignToolSubjectName']=0D
if PayloadJsonDescriptorList[Index].OpenSslSignerPrivateCertFi=
le is None:=0D
del PayloadField ['OpenSslSignerPrivateCertFile']=0D
if PayloadJsonDescriptorList[Index].OpenSslOtherPublicCertFile=
is None:=0D
@@ -402,6 +412,9 @@ if __name__ =3D=3D '__main__':
if args.SignToolPfxFile:=0D
print ('GenerateCapsule: error: Argument --pfx-file conflicts =
with Argument -j')=0D
sys.exit (1)=0D
+ if args.SignToolSubjectName:=0D
+ print ('GenerateCapsule: error: Argument --SubjectName conflic=
ts with Argument -j')=0D
+ sys.exit (1)=0D
if args.OpenSslSignerPrivateCertFile:=0D
print ('GenerateCapsule: error: Argument --signer-private-cert=
conflicts with Argument -j')=0D
sys.exit (1)=0D
@@ -425,6 +438,7 @@ if __name__ =3D=3D '__main__':
HardwareInstance =3D 0,=0D
UpdateImageIndex =3D 1,=0D
SignToolPfxFile =3D None,=0D
+ SignToolSubjectName =3D None,=0D
OpenSslSignerPrivateCertFile =3D None,=0D
OpenSslOtherPublicCertFile =3D None,=0D
OpenSslTrustedPublicCertFile =3D None,=0D
@@ -439,13 +453,15 @@ if __name__ =3D=3D '__main__':
self.HardwareInstance =3D HardwareInstance=0D
self.UpdateImageIndex =3D UpdateImageIndex=0D
self.SignToolPfxFile =3D SignToolPfxFile=0D
+ self.SignToolSubjectName =3D SignToolSubjectName=0D
self.OpenSslSignerPrivateCertFile =3D OpenSslSignerPrivateCert=
File=0D
self.OpenSslOtherPublicCertFile =3D OpenSslOtherPublicCertFi=
le=0D
self.OpenSslTrustedPublicCertFile =3D OpenSslTrustedPublicCert=
File=0D
self.SigningToolPath =3D SigningToolPath=0D
self.DepexExp =3D DepexExp=0D
=0D
- self.UseSignTool =3D self.SignToolPfxFile is not None=0D
+ self.UseSignTool =3D (self.SignToolPfxFile is not None or=0D
+ self.SignToolSubjectName is not None)=0D
self.UseOpenSsl =3D (self.OpenSslSignerPrivateCertFile is not=
None and=0D
self.OpenSslOtherPublicCertFile is not Non=
e and=0D
self.OpenSslTrustedPublicCertFile is not N=
one)=0D
@@ -504,8 +520,9 @@ if __name__ =3D=3D '__main__':
raise argparse.ArgumentTypeError ('--update-image-=
index must be an integer in range 0x0..0xff')=0D
=0D
if self.UseSignTool:=0D
- self.SignToolPfxFile.close()=0D
- self.SignToolPfxFile =3D self.SignToolPfxFile.name=0D
+ if self.SignToolPfxFile is not None:=0D
+ self.SignToolPfxFile.close()=0D
+ self.SignToolPfxFile =3D self.SignToolPfxFile.name=0D
if self.UseOpenSsl:=0D
self.OpenSslSignerPrivateCertFile.close()=0D
self.OpenSslOtherPublicCertFile.close()=0D
@@ -548,6 +565,7 @@ if __name__ =3D=3D '__main__':
args.HardwareInstance,=0D
args.UpdateImageIndex,=0D
args.SignToolPfxFile,=0D
+ args.SignToolSubjectName,=0D
args.OpenSslSignerPrivateCertF=
ile,=0D
args.OpenSslOtherPublicCertFil=
e,=0D
args.OpenSslTrustedPublicCertF=
ile,=0D
@@ -590,6 +608,7 @@ if __name__ =3D=3D '__main__':
Result + struct.pack ('<Q', SinglePayloadDescr=
iptor.MonotonicCount),=0D
SinglePayloadDescriptor.SigningToolPath,=0D
SinglePayloadDescriptor.SignToolPfxFile,=0D
+ SinglePayloadDescriptor.SignToolSubjectName,=0D
Verbose =3D args.Verbose=0D
)=0D
else:=0D
@@ -671,6 +690,7 @@ if __name__ =3D=3D '__main__':
args.HardwareInstance,=0D
args.UpdateImageIndex,=0D
args.SignToolPfxFile,=0D
+ args.SignSubjectName,=0D
args.OpenSslSignerPrivateCertF=
ile,=0D
args.OpenSslOtherPublicCertFil=
e,=0D
args.OpenSslTrustedPublicCertF=
ile,=0D
@@ -715,6 +735,7 @@ if __name__ =3D=3D '__main__':
HardwareIn=
stance,=0D
UpdateImag=
eIndex,=0D
PayloadDes=
criptorList[Index].SignToolPfxFile,=0D
+ PayloadDes=
criptorList[Index].SignToolSubjectName,=0D
PayloadDes=
criptorList[Index].OpenSslSignerPrivateCertFile,=0D
PayloadDes=
criptorList[Index].OpenSslOtherPublicCertFile,=0D
PayloadDes=
criptorList[Index].OpenSslTrustedPublicCertFile,=0D
@@ -753,6 +774,7 @@ if __name__ =3D=3D '__main__':
HardwareInstan=
ce,=0D
UpdateImageInd=
ex,=0D
PayloadDescrip=
torList[Index].SignToolPfxFile,=0D
+ PayloadDescrip=
torList[Index].SignToolSubjectName,=0D
PayloadDescrip=
torList[Index].OpenSslSignerPrivateCertFile,=0D
PayloadDescrip=
torList[Index].OpenSslOtherPublicCertFile,=0D
PayloadDescrip=
torList[Index].OpenSslTrustedPublicCertFile,=0D
@@ -785,6 +807,7 @@ if __name__ =3D=3D '__main__':
FmpAuthHeader.CertData,=0D
SinglePayloadDescriptor.Signing=
ToolPath,=0D
SinglePayloadDescriptor.SignToo=
lPfxFile,=0D
+ SinglePayloadDescriptor.SignToo=
lSubjectName,=0D
Verbose =3D args.Verbose=0D
)=0D
else:=0D
@@ -968,6 +991,8 @@ if __name__ =3D=3D '__main__':
=0D
parser.add_argument ("--pfx-file", dest=3D'SignToolPfxFile', type=3Dar=
gparse.FileType('rb'),=0D
help=3D"signtool PFX certificate filename.")=0D
+ parser.add_argument ("--subject-name", dest=3D'SignToolSubjectName',=0D
+ help=3D"signtool certificate subject name.")=0D
=0D
parser.add_argument ("--signer-private-cert", dest=3D'OpenSslSignerPri=
vateCertFile', type=3Dargparse.FileType('rb'),=0D
help=3D"OpenSSL signer private certificate filena=
me.")=0D
--=20
2.37.0.windows.1


Re: [PATCH v3] BaseTools/Capsule: Add support for signtool to input subject name to sign capsule file

Bob Feng
 

-----Original Message-----
From: gaoliming <gaoliming@...>
Sent: Monday, July 25, 2022 12:27 PM
To: devel@edk2.groups.io; Lin, Jason1 <jason1.lin@...>
Cc: Feng, Bob C <bob.c.feng@...>; Chen, Christine <yuwei.chen@...>; Kinney, Michael D <michael.d.kinney@...>; Chiang, Dakota <dakota.chiang@...>
Subject: 回复: [edk2-devel] [PATCH v3] BaseTools/Capsule: Add support for signtool to input subject name to sign capsule file

Jason:
Thanks for you to add the detail usage model in BZ 3928. I have no other comments. Reviewed-by: Liming Gao <gaoliming@...>

Thanks
Liming
-----邮件原件-----
发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Lin, Jason1
发送时间: 2022年7月8日 19:42
收件人: devel@edk2.groups.io
抄送: Jason1 Lin <jason1.lin@...>; Bob Feng
<bob.c.feng@...>; Liming Gao <gaoliming@...>; Yuwei
Chen <yuwei.chen@...>; Michael D Kinney
<michael.d.kinney@...>; Dakota Chiang <dakota.chiang@...>
主题: [edk2-devel] [PATCH v3] BaseTools/Capsule: Add support for
signtool
to
input subject name to sign capsule file

From: Jason1 Lin <jason1.lin@...>

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

Windows-based system using signtool.exe to sign the capsule.
Add the support to using "--subject-name" argument to assign the
subject name used to sign the capsule file.
This argument would pass to signtool.exe as a part of input argument
with "/n" flag.

NOTE: If using signtool.exe to sign capsule at least need to
choose one of "--pfx-file" and "--subject-name"
argument to input the value.

Signed-off-by: Jason1 Lin <jason1.lin@...>
Cc: Bob Feng <bob.c.feng@...>
Cc: Liming Gao <gaoliming@...>
Cc: Yuwei Chen <yuwei.chen@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Dakota Chiang <dakota.chiang@...>
---
BaseTools/Source/Python/Capsule/GenerateCapsule.py | 43
++++++++++++++++----
1 file changed, 34 insertions(+), 9 deletions(-)

diff --git a/BaseTools/Source/Python/Capsule/GenerateCapsule.py
b/BaseTools/Source/Python/Capsule/GenerateCapsule.py
index b8039db878..35435946c6 100644
--- a/BaseTools/Source/Python/Capsule/GenerateCapsule.py
+++ b/BaseTools/Source/Python/Capsule/GenerateCapsule.py
@@ -10,7 +10,7 @@
# keep the tool as simple as possible, it has the following limitations:

# * Do not support vendor code bytes in a capsule.

#

-# Copyright (c) 2018 - 2019, Intel Corporation. All rights
reserved.<BR>

+# Copyright (c) 2018 - 2022, Intel Corporation. All rights
+reserved.<BR>

# SPDX-License-Identifier: BSD-2-Clause-Patent

#



@@ -38,11 +38,11 @@ from Common.Edk2.Capsule.FmpPayloadHeader
import FmpPayloadHeaderClass
# Globals for help information

#

__prog__ = 'GenerateCapsule'

-__version__ = '0.9'

-__copyright__ = 'Copyright (c) 2018, Intel Corporation. All rights
reserved.'

+__version__ = '0.10'

+__copyright__ = 'Copyright (c) 2022, Intel Corporation. All rights
reserved.'

__description__ = 'Generate a capsule.\n'



-def SignPayloadSignTool (Payload, ToolPath, PfxFile, Verbose = False):

+def SignPayloadSignTool (Payload, ToolPath, PfxFile, SubjectName,
+Verbose
=
False):

#

# Create a temporary directory

#

@@ -72,7 +72,10 @@ def SignPayloadSignTool (Payload, ToolPath,
PfxFile, Verbose = False):
Command = Command + '"{Path}" '.format (Path = os.path.join
(ToolPath,
'signtool.exe'))

Command = Command + 'sign /fd sha256 /p7ce DetachedSignedData
/p7co 1.2.840.113549.1.7.2 '

Command = Command + '/p7 {TempDir} '.format (TempDir =
TempDirectoryName)

- Command = Command + '/f {PfxFile} '.format (PfxFile = PfxFile)

+ if PfxFile is not None:

+ Command = Command + '/f {PfxFile} '.format (PfxFile =
+ PfxFile)

+ if SubjectName is not None:

+ Command = Command + '/n {SubjectName} '.format
(SubjectName = SubjectName)

Command = Command + TempFileName

if Verbose:

print (Command)

@@ -105,7 +108,7 @@ def SignPayloadSignTool (Payload, ToolPath,
PfxFile, Verbose = False):
shutil.rmtree (TempDirectoryName)

return Signature



-def VerifyPayloadSignTool (Payload, CertData, ToolPath, PfxFile,
Verbose
=
False):

+def VerifyPayloadSignTool (Payload, CertData, ToolPath, PfxFile,
SubjectName,
Verbose = False):

print ('signtool verify is not supported.')

raise ValueError ('GenerateCapsule: error: signtool verify is not
supported.')



@@ -249,6 +252,7 @@ if __name__ == '__main__':
HardwareInstance = ConvertJsonValue
(Config, 'HardwareInstance', ValidateUnsignedInteger, Required =
False, Default = 0)

MonotonicCount = ConvertJsonValue
(Config, 'MonotonicCount', ValidateUnsignedInteger, Required = False,
Default
= 0)

SignToolPfxFile = ConvertJsonValue (Config,
'SignToolPfxFile', os.path.expandvars, Required = False, Default =
None,
Open
= True)

+ SignToolSubjectName = ConvertJsonValue (Config,
'SignToolSubjectName', os.path.expandvars, Required = False, Default =
None,
Open = True)

OpenSslSignerPrivateCertFile = ConvertJsonValue (Config,
'OpenSslSignerPrivateCertFile', os.path.expandvars, Required = False,
Default
= None, Open = True)

OpenSslOtherPublicCertFile = ConvertJsonValue (Config,
'OpenSslOtherPublicCertFile', os.path.expandvars, Required = False,
Default =
None, Open = True)

OpenSslTrustedPublicCertFile = ConvertJsonValue (Config,
'OpenSslTrustedPublicCertFile', os.path.expandvars, Required = False,
Default
= None, Open = True)

@@ -264,6 +268,7 @@ if __name__ == '__main__':
HardwareInstance,

UpdateImageIndex,

SignToolPfxFile,

+
SignToolSubjectName,


OpenSslSignerPrivateCertFile,


OpenSslOtherPublicCertFile,


OpenSslTrustedPublicCertFile,

@@ -303,6 +308,7 @@ if __name__ == '__main__':
UpdateImageIndex = ConvertJsonValue
(Config, 'UpdateImageIndex', ValidateUnsignedInteger, Required =
False, Default = 1)

MonotonicCount = ConvertJsonValue
(Config, 'MonotonicCount', ValidateUnsignedInteger, Required = False,
Default
= 0)

SignToolPfxFile = ConvertJsonValue (Config,
'SignToolPfxFile', os.path.expandvars, Required = False, Default =
None,
Open
= True)

+ SignToolSubjectName = ConvertJsonValue (Config,
'SignToolSubjectName', os.path.expandvars, Required = False, Default =
None,
Open = True)

OpenSslSignerPrivateCertFile = ConvertJsonValue (Config,
'OpenSslSignerPrivateCertFile', os.path.expandvars, Required = False,
Default
= None, Open = True)

OpenSslOtherPublicCertFile = ConvertJsonValue (Config,
'OpenSslOtherPublicCertFile', os.path.expandvars, Required = False,
Default =
None, Open = True)

OpenSslTrustedPublicCertFile = ConvertJsonValue (Config,
'OpenSslTrustedPublicCertFile', os.path.expandvars, Required = False,
Default
= None, Open = True)

@@ -329,6 +335,7 @@ if __name__ == '__main__':
HardwareInstance,

UpdateImageIndex,

SignToolPfxFile,

+
SignToolSubjectName,


OpenSslSignerPrivateCertFile,


OpenSslOtherPublicCertFile,


OpenSslTrustedPublicCertFile,

@@ -348,6 +355,7 @@ if __name__ == '__main__':
"HardwareInstance":
str(PayloadDescriptor.HardwareInstance),

"UpdateImageIndex":
str(PayloadDescriptor.UpdateImageIndex),

"SignToolPfxFile":
str(PayloadDescriptor.SignToolPfxFile),

+ "SignToolSubjectName":
str(PayloadDescriptor.SignToolSubjectName),

"OpenSslSignerPrivateCertFile":
str(PayloadDescriptor.OpenSslSignerPrivateCertFile),

"OpenSslOtherPublicCertFile":
str(PayloadDescriptor.OpenSslOtherPublicCertFile),

"OpenSslTrustedPublicCertFile":
str(PayloadDescriptor.OpenSslTrustedPublicCertFile),

@@ -363,6 +371,8 @@ if __name__ == '__main__':
for PayloadField in PayloadSection:

if PayloadJsonDescriptorList[Index].SignToolPfxFile is None:

del PayloadField ['SignToolPfxFile']

+ if PayloadJsonDescriptorList[Index].SignToolSubjectName
+ is
None:

+ del PayloadField ['SignToolSubjectName']

if
PayloadJsonDescriptorList[Index].OpenSslSignerPrivateCertFile is None:

del PayloadField ['OpenSslSignerPrivateCertFile']

if
PayloadJsonDescriptorList[Index].OpenSslOtherPublicCertFile is None:

@@ -402,6 +412,9 @@ if __name__ == '__main__':
if args.SignToolPfxFile:

print ('GenerateCapsule: error: Argument --pfx-file
conflicts with Argument -j')

sys.exit (1)

+ if args.SignToolSubjectName:

+ print ('GenerateCapsule: error: Argument --SubjectName
conflicts with Argument -j')

+ sys.exit (1)

if args.OpenSslSignerPrivateCertFile:

print ('GenerateCapsule: error: Argument
--signer-private-cert conflicts with Argument -j')

sys.exit (1)

@@ -425,6 +438,7 @@ if __name__ == '__main__':
HardwareInstance = 0,

UpdateImageIndex = 1,

SignToolPfxFile = None,

+ SignToolSubjectName = None,

OpenSslSignerPrivateCertFile = None,

OpenSslOtherPublicCertFile = None,

OpenSslTrustedPublicCertFile = None,

@@ -439,13 +453,15 @@ if __name__ == '__main__':
self.HardwareInstance = HardwareInstance

self.UpdateImageIndex = UpdateImageIndex

self.SignToolPfxFile = SignToolPfxFile

+ self.SignToolSubjectName = SignToolSubjectName

self.OpenSslSignerPrivateCertFile =
OpenSslSignerPrivateCertFile

self.OpenSslOtherPublicCertFile =
OpenSslOtherPublicCertFile

self.OpenSslTrustedPublicCertFile =
OpenSslTrustedPublicCertFile

self.SigningToolPath = SigningToolPath

self.DepexExp = DepexExp



- self.UseSignTool = self.SignToolPfxFile is not None

+ self.UseSignTool = (self.SignToolPfxFile is not None or

+ self.SignToolSubjectName is not
None)

self.UseOpenSsl = (self.OpenSslSignerPrivateCertFile is
not None and

self.OpenSslOtherPublicCertFile is
not None and

self.OpenSslTrustedPublicCertFile is
not None)

@@ -504,8 +520,9 @@ if __name__ == '__main__':
raise argparse.ArgumentTypeError
('--update-image-index must be an integer in range 0x0..0xff')



if self.UseSignTool:

- self.SignToolPfxFile.close()

- self.SignToolPfxFile = self.SignToolPfxFile.name

+ if self.SignToolPfxFile is not None:

+ self.SignToolPfxFile.close()

+ self.SignToolPfxFile = self.SignToolPfxFile.name

if self.UseOpenSsl:

self.OpenSslSignerPrivateCertFile.close()

self.OpenSslOtherPublicCertFile.close()

@@ -548,6 +565,7 @@ if __name__ == '__main__':

args.HardwareInstance,


args.UpdateImageIndex,

args.SignToolPfxFile,

+
args.SignToolSubjectName,


args.OpenSslSignerPrivateCertFile,


args.OpenSslOtherPublicCertFile,


args.OpenSslTrustedPublicCertFile,

@@ -590,6 +608,7 @@ if __name__ == '__main__':
Result + struct.pack ('<Q',
SinglePayloadDescriptor.MonotonicCount),

SinglePayloadDescriptor.SigningToolPath,

SinglePayloadDescriptor.SignToolPfxFile,

+
SinglePayloadDescriptor.SignToolSubjectName,

Verbose = args.Verbose

)

else:

@@ -671,6 +690,7 @@ if __name__ == '__main__':

args.HardwareInstance,


args.UpdateImageIndex,

args.SignToolPfxFile,

+
args.SignSubjectName,


args.OpenSslSignerPrivateCertFile,


args.OpenSslOtherPublicCertFile,


args.OpenSslTrustedPublicCertFile,

@@ -715,6 +735,7 @@ if __name__ == '__main__':

HardwareInstance,


UpdateImageIndex,


PayloadDescriptorList[Index].SignToolPfxFile,

+
PayloadDescriptorList[Index].SignToolSubjectName,


PayloadDescriptorList[Index].OpenSslSignerPrivateCertFile,


PayloadDescriptorList[Index].OpenSslOtherPublicCertFile,


PayloadDescriptorList[Index].OpenSslTrustedPublicCertFile,

@@ -753,6 +774,7 @@ if __name__ == '__main__':

HardwareInstance,


UpdateImageIndex,


PayloadDescriptorList[Index].SignToolPfxFile,

+
PayloadDescriptorList[Index].SignToolSubjectName,


PayloadDescriptorList[Index].OpenSslSignerPrivateCertFile,


PayloadDescriptorList[Index].OpenSslOtherPublicCertFile,


PayloadDescriptorList[Index].OpenSslTrustedPublicCertFile,

@@ -785,6 +807,7 @@ if __name__ == '__main__':

FmpAuthHeader.CertData,


SinglePayloadDescriptor.SigningToolPath,


SinglePayloadDescriptor.SignToolPfxFile,

+
SinglePayloadDescriptor.SignToolSubjectName,

Verbose = args.Verbose

)

else:

@@ -968,6 +991,8 @@ if __name__ == '__main__':


parser.add_argument ("--pfx-file", dest='SignToolPfxFile',
type=argparse.FileType('rb'),

help="signtool PFX certificate filename.")

+ parser.add_argument ("--subject-name",
+ dest='SignToolSubjectName',

+ help="signtool certificate subject name.")



parser.add_argument ("--signer-private-cert",
dest='OpenSslSignerPrivateCertFile', type=argparse.FileType('rb'),

help="OpenSSL signer private certificate
filename.")

--
2.37.0.windows.1



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


Re: [PATCH 2/2] Platform/Sgi: Add serial debug controller to SSDT

Rohit Mathew
 

Hi Sami/Thanu,

Please find my response inline - 

On Mon, Jul 25, 2022 at 02:54 PM, Thanu Rangarajan <Thanu.Rangarajan@...> wrote:

Hi Rohit,

The decision to use the SBSA defined HID for the Generic UART was taken after extensive discussions within the Arm ecosystem. And as Sami points out, now that formal Linux driver support for this HID is available, it would be good if it is used by other components in the stack as well.

 

+ Samer for any additional comments/clarifications.

 

Regards,

Thanu

From: Sami Mujawar <Sami.Mujawar@...>
Date: Monday, 25 July 2022 at 16:12
To: Rohit Mathew <Rohit.Mathew@...>, "devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: Thanu Rangarajan <Thanu.Rangarajan@...>, nd <nd@...>
Subject: Re: [edk2-devel] [PATCH 2/2] Platform/Sgi: Add serial debug controller to SSDT

 

Hi Rohit,

Please find my response inline marked [SAMI].

Regards,

Sami Mujawar

On 22/07/2022 01:46 pm, Rohit Mathew wrote:

Hi Sami,

Thank you for the review.
Regarding the use of Dynamic Tables Framework, there are no short term plans to migrate to it. Please find my response for your comment inline - 

On Thu, Jul 21, 2022 at 01:42 PM, Sami Mujawar wrote:

Hi Rohit,

Have you considered moving to use Dynamic Tables Framework? There is
just too much repetition in this series which can be easily avoided. It
will also make the code more maintainable.

Apart from this I have a comment marked inline as [SAMI].

Regards,

Sami Mujawar

On 04/07/2022 05:59 pm, Rohit Mathew wrote:

Add a new device entry in the SSDT ACPI table to describe the serial
port used as the debug port. On the Neoverse reference design platforms,
the UART0 port of the SoC is used as the debug port.

Signed-off-by: Rohit Mathew <rohit.mathew@...>
---
Platform/ARM/SgiPkg/AcpiTables/RdE1EdgeAcpiTables.inf | 1 +
Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeAcpiTables.inf | 1 +
Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeX2AcpiTables.inf | 1 +
Platform/ARM/SgiPkg/AcpiTables/RdN2AcpiTables.inf | 1 +
Platform/ARM/SgiPkg/AcpiTables/RdN2Cfg1AcpiTables.inf | 1 +
Platform/ARM/SgiPkg/AcpiTables/RdV1AcpiTables.inf | 1 +
Platform/ARM/SgiPkg/AcpiTables/RdV1McAcpiTables.inf | 1 +
Platform/ARM/SgiPkg/AcpiTables/Sgi575AcpiTables.inf | 1 +
Platform/ARM/SgiPkg/AcpiTables/SsdtRos.asl | 15 +++++++++++++++
9 files changed, 23 insertions(+)

diff --git a/Platform/ARM/SgiPkg/AcpiTables/RdE1EdgeAcpiTables.inf b/Platform/ARM/SgiPkg/AcpiTables/RdE1EdgeAcpiTables.inf
index d2935f1e73e1..d46ae0274d90 100644
--- a/Platform/ARM/SgiPkg/AcpiTables/RdE1EdgeAcpiTables.inf
+++ b/Platform/ARM/SgiPkg/AcpiTables/RdE1EdgeAcpiTables.inf
@@ -39,6 +39,7 @@ [Packages]
[FixedPcd]
gArmPlatformTokenSpaceGuid.PcdCoreCount
gArmPlatformTokenSpaceGuid.PcdClusterCount
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgInterrupt
gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
gArmPlatformTokenSpaceGuid.PL011UartInterrupt

diff --git a/Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeAcpiTables.inf b/Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeAcpiTables.inf
index 73f47ece7718..4bf681d3bc2e 100644
--- a/Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeAcpiTables.inf
+++ b/Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeAcpiTables.inf
@@ -39,6 +39,7 @@ [Packages]
[FixedPcd]
gArmPlatformTokenSpaceGuid.PcdCoreCount
gArmPlatformTokenSpaceGuid.PcdClusterCount
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgInterrupt
gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
gArmPlatformTokenSpaceGuid.PL011UartInterrupt

diff --git a/Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeX2AcpiTables.inf b/Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeX2AcpiTables.inf
index da14120bde69..89f532217ceb 100644
--- a/Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeX2AcpiTables.inf
+++ b/Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeX2AcpiTables.inf
@@ -41,6 +41,7 @@ [Packages]
[FixedPcd]
gArmPlatformTokenSpaceGuid.PcdCoreCount
gArmPlatformTokenSpaceGuid.PcdClusterCount
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgInterrupt
gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
gArmPlatformTokenSpaceGuid.PL011UartInterrupt

diff --git a/Platform/ARM/SgiPkg/AcpiTables/RdN2AcpiTables.inf b/Platform/ARM/SgiPkg/AcpiTables/RdN2AcpiTables.inf
index 90976250445e..66d5422df36b 100644
--- a/Platform/ARM/SgiPkg/AcpiTables/RdN2AcpiTables.inf
+++ b/Platform/ARM/SgiPkg/AcpiTables/RdN2AcpiTables.inf
@@ -37,6 +37,7 @@ [Packages]
Platform/ARM/SgiPkg/SgiPlatform.dec

[FixedPcd]
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgInterrupt
gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
gArmPlatformTokenSpaceGuid.PL011UartInterrupt
gArmPlatformTokenSpaceGuid.PcdCoreCount
diff --git a/Platform/ARM/SgiPkg/AcpiTables/RdN2Cfg1AcpiTables.inf b/Platform/ARM/SgiPkg/AcpiTables/RdN2Cfg1AcpiTables.inf
index 95fb446c105d..742734ab7348 100644
--- a/Platform/ARM/SgiPkg/AcpiTables/RdN2Cfg1AcpiTables.inf
+++ b/Platform/ARM/SgiPkg/AcpiTables/RdN2Cfg1AcpiTables.inf
@@ -37,6 +37,7 @@ [Packages]
Platform/ARM/SgiPkg/SgiPlatform.dec

[FixedPcd]
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgInterrupt
gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
gArmPlatformTokenSpaceGuid.PcdCoreCount
gArmPlatformTokenSpaceGuid.PcdClusterCount
diff --git a/Platform/ARM/SgiPkg/AcpiTables/RdV1AcpiTables.inf b/Platform/ARM/SgiPkg/AcpiTables/RdV1AcpiTables.inf
index 3540575dd641..cc41dda1a135 100644
--- a/Platform/ARM/SgiPkg/AcpiTables/RdV1AcpiTables.inf
+++ b/Platform/ARM/SgiPkg/AcpiTables/RdV1AcpiTables.inf
@@ -37,6 +37,7 @@ [Packages]
Platform/ARM/SgiPkg/SgiPlatform.dec

[FixedPcd]
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgInterrupt
gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
gArmPlatformTokenSpaceGuid.PL011UartInterrupt
gArmPlatformTokenSpaceGuid.PcdCoreCount
diff --git a/Platform/ARM/SgiPkg/AcpiTables/RdV1McAcpiTables.inf b/Platform/ARM/SgiPkg/AcpiTables/RdV1McAcpiTables.inf
index c6bd69b4a538..ecb42bf3cc33 100644
--- a/Platform/ARM/SgiPkg/AcpiTables/RdV1McAcpiTables.inf
+++ b/Platform/ARM/SgiPkg/AcpiTables/RdV1McAcpiTables.inf
@@ -39,6 +39,7 @@ [Packages]
Platform/ARM/SgiPkg/SgiPlatform.dec

[FixedPcd]
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgInterrupt
gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
gArmPlatformTokenSpaceGuid.PL011UartInterrupt
gArmPlatformTokenSpaceGuid.PcdCoreCount
diff --git a/Platform/ARM/SgiPkg/AcpiTables/Sgi575AcpiTables.inf b/Platform/ARM/SgiPkg/AcpiTables/Sgi575AcpiTables.inf
index cb3f3fcdb9b6..379b5c9e6122 100644
--- a/Platform/ARM/SgiPkg/AcpiTables/Sgi575AcpiTables.inf
+++ b/Platform/ARM/SgiPkg/AcpiTables/Sgi575AcpiTables.inf
@@ -39,6 +39,7 @@ [Packages]
[FixedPcd]
gArmPlatformTokenSpaceGuid.PcdCoreCount
gArmPlatformTokenSpaceGuid.PcdClusterCount
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgInterrupt
gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
gArmPlatformTokenSpaceGuid.PL011UartInterrupt

diff --git a/Platform/ARM/SgiPkg/AcpiTables/SsdtRos.asl b/Platform/ARM/SgiPkg/AcpiTables/SsdtRos.asl
index fd20c67e1225..ab8578072836 100644
--- a/Platform/ARM/SgiPkg/AcpiTables/SsdtRos.asl
+++ b/Platform/ARM/SgiPkg/AcpiTables/SsdtRos.asl
@@ -29,6 +29,21 @@ DefinitionBlock ("SsdtRosTable.aml", "SSDT", 2, "ARMLTD", "ARMSGI",
})
}

+ Device (COM1) {
+ Name (_HID, "ARMH0011")
+ Name (_CID, "ARMH0011")

[SAMI] Any reason for not using  ARMHB000 (see Section 2.3 of the ACPI
for Arm Components 1.1 specification)?

[Rohit]: COM1 is based on PL011. Since PL011 would satisfy SBSA compliance, we have used PL011's HID.

[SAMI] Following is an extract from Section 2.3 of the 'ACPI for Arm Components 1.1' specification.

"Some operating systems use the PL011 HID (see Table 5 above)
to bind to the Arm Generic UART in the system. While this
practice is flawed and not encouraged by Arm, Arm
acknowledges that it must be permitted until formal support for
the Arm Generic UART HID is made available in these operating
systems.
Arm strongly recommends use of the Arm Generic UART HID
going forward."

1. The Arm Generic UART is a subset of PL011. This means using the ARMHB000 should not be an issue.

2. This file is common to all platforms in SgiPkg, which are infrastructure platforms.

3. Some opreating systems (like Linux) have already integrated support for ARMHB000.

    Ref: serial: pl011: Add ACPI SBSA UART match id

Considering the above, I think ARMHB000 should be used, here.

[/SAMI]

[Rohit] Apologies for not adding more context earlier. RD FVPs instantiates PL011 UART and not the Generic SBSA UART. Although 'Generic UART' would work as it is a subset of PL011, PL011 HID accurately describes the UART controllers for infra platforms. I'm not sure if this is any better explanation; Please let me know if you think otherwise.
[/Rohit]

 



+ Name (_UID, One)
+ Name (_STA, 0xF)
+ Name (_CRS, ResourceTemplate () {
+ Memory32Fixed (
+ ReadWrite,
+ FixedPcdGet64 (PcdSerialDbgRegisterBase),
+ 0x1000
+ )
+ Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { FixedPcdGet32 (PcdSerialDbgInterrupt) }
+ })
+ }
+
// VIRTIO DISK
Device (VR00) {
Name (_HID, "LNRO0005")

Regards,
Rohit

IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.


Re: [edk2-staging][PATCH v2 2/2] edk2-staging/EmulatorPkg: Introduce Hii2RedfishBiosDxe driver

Chang, Abner
 

[AMD Official Use Only - General]

Reviewed-by: Abner Chang <abner.chang@...>

-----Original Message-----
From: Nickle Wang <nickle.wang@...>
Sent: Monday, July 25, 2022 9:36 AM
To: devel@edk2.groups.io
Cc: Andrew Fish <afish@...>; Ray Ni <ray.ni@...>; Chang,
Abner <Abner.Chang@...>; Yang, Atom <Atom.Yang@...>;
Nick Ramirez <nramirez@...>
Subject: [edk2-staging][PATCH v2 2/2] edk2-staging/EmulatorPkg: Introduce
Hii2RedfishBiosDxe driver

[CAUTION: External Email]

Add Hii2RedfishBiosDxe driver with configure language defined in UNI file in
order to demonstrate the use of Redfish Platform Config Protocol. Feature
drivers under RedfishClientPkg will work with this driver and provide the
REST data to Redfish service.

Signed-off-by: Nickle Wang <nickle.wang@...>
Cc: Andrew Fish <afish@...>
Cc: Ray Ni <ray.ni@...>
Cc: Abner Chang <abner.chang@...>
Cc: Yang Atom <Atom.Yang@...>
Cc: Nick Ramirez <nramirez@...>
---
EmulatorPkg/EmulatorPkg.dec | 1 +
EmulatorPkg/EmulatorPkg.dsc | 1 +
EmulatorPkg/EmulatorPkg.fdf | 1 +
.../Hii2RedfishBiosDxe/Hii2RedfishBiosData.h | 46 +++
.../Hii2RedfishBiosDxe/Hii2RedfishBiosDxe.c | 291 ++++++++++++++++++
.../Hii2RedfishBiosDxe/Hii2RedfishBiosDxe.h | 44 +++
.../Hii2RedfishBiosDxe/Hii2RedfishBiosDxe.inf | 55 ++++
.../Hii2RedfishBiosDxeMap.uni | 20 ++
.../Hii2RedfishBiosDxeStrings.uni | 30 ++
.../Hii2RedfishBiosDxe/Hii2RedfishBiosVfr.vfr | 67 ++++
10 files changed, 556 insertions(+)
create mode 100644 EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosData.h
create mode 100644 EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosDxe.c
create mode 100644 EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosDxe.h
create mode 100644
EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosDxe.inf
create mode 100644
EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosDxeMap.uni
create mode 100644
EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosDxeStrings.uni
create mode 100644 EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosVfr.vfr

diff --git a/EmulatorPkg/EmulatorPkg.dec b/EmulatorPkg/EmulatorPkg.dec
index 52a62c09c9..e782b15266 100644
--- a/EmulatorPkg/EmulatorPkg.dec
+++ b/EmulatorPkg/EmulatorPkg.dec
@@ -49,6 +49,7 @@
gEmuRedfishServiceGuid = { 0x3fb208ac, 0x2185, 0x498c, { 0xbf, 0x46,
0xdc, 0x23, 0xda, 0x58, 0x7b, 0x55 } }
gHii2RedfishMemoryFormsetGuid = { 0xC2BE579E, 0x3C57, 0x499C, { 0xA9,
0xDF, 0xE6, 0x23, 0x8A, 0x49, 0x64, 0xF8 }}
gHii2RedfishBootFormsetGuid = { 0x8399a787, 0x108e, 0x4e53, { 0x9e, 0xde,
0x4b, 0x18, 0xcc, 0x9e, 0xab, 0x3b }}
+ gHii2RedfishBiosFormsetGuid = { 0xC2724AD1, 0x4049, 0x2404, { 0xF8,
+ 0xCE, 0x01, 0xA7, 0x9C, 0xEC, 0x16, 0xF6 }}

[PcdsFeatureFlag]
## If TRUE, if symbols only load on breakpoints and gdb entry diff --git
a/EmulatorPkg/EmulatorPkg.dsc b/EmulatorPkg/EmulatorPkg.dsc index
1d59b4a1dd..dd1d9ef9ec 100644
--- a/EmulatorPkg/EmulatorPkg.dsc
+++ b/EmulatorPkg/EmulatorPkg.dsc
@@ -491,6 +491,7 @@
!if $(REDFISH_ENABLE) == TRUE
EmulatorPkg/Hii2RedfishMemoryDxe/Hii2RedfishMemoryDxe.inf
EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootDxe.inf
+ EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosDxe.inf
!endif
!include RedfishPkg/Redfish.dsc.inc
!include RedfishClientPkg/RedfishClient.dsc.inc
diff --git a/EmulatorPkg/EmulatorPkg.fdf b/EmulatorPkg/EmulatorPkg.fdf
index f9ff4320d9..9e594533d8 100644
--- a/EmulatorPkg/EmulatorPkg.fdf
+++ b/EmulatorPkg/EmulatorPkg.fdf
@@ -215,6 +215,7 @@ INF EmulatorPkg/EmuSnpDxe/EmuSnpDxe.inf
!if $(REDFISH_ENABLE) == TRUE
INF EmulatorPkg/Hii2RedfishMemoryDxe/Hii2RedfishMemoryDxe.inf
INF EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootDxe.inf
+ INF EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosDxe.inf
!endif
!include RedfishPkg/Redfish.fdf.inc
!include RedfishClientPkg/RedfishClient.fdf.inc
diff --git a/EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosData.h
b/EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosData.h
new file mode 100644
index 0000000000..1b27dfd168
--- /dev/null
+++ b/EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosData.h
@@ -0,0 +1,46 @@
+/** @file
+ The header file of HII-to-Redfish BIOS example driver.
+
+ (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef HII_2_REDFISH_BIOS_DATA_H_
+#define HII_2_REDFISH_BIOS_DATA_H_
+
+#include <Uefi/UefiMultiPhase.h>
+#include <Guid/HiiPlatformSetupFormset.h>
+
+#define HII_2_REDFISH_BIOS_FORMSET_GUID \
+ { \
+ 0xC2724AD1, 0x4049, 0x2404, { 0xF8, 0xCE, 0x01, 0xA7, 0x9C, 0xEC, 0x16,
0xF6 } \
+ }
+
+extern EFI_GUID gHii2RedfishBiosFormsetGuid;
+
+#define FORM_ID 0x001
+#define FROM_ID_BIOS_OPTION_1 0x002
+#define FROM_ID_BIOS_OPTION_2 0x003
+#define FROM_ID_BIOS_OPTION_3 0x004
+#define FROM_ID_BIOS_OPTION_4 0x005
+
+#define ID_STRING_MIN 0
+#define ID_STRING_MAX 15
+#define ID_STRING_MAX_WITH_TERMINATOR 16
+
+#pragma pack()
+
+//
+// Definiton of HII_2_REDFISH_BIOS_VARSTORE_DATA // typedef struct {
+ UINT8 RefishBiosOption1Data;
+ CHAR16 RefishBiosOption2Data [ID_STRING_MAX_WITH_TERMINATOR];
+ UINT8 RefishBiosOption3Data;
+ UINT8 RefishBiosOption4Data;
+ UINT8 Reserved;
+} HII_2_REDFISH_BIOS_EFI_VARSTORE_DATA;
+
+#endif
diff --git a/EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosDxe.c
b/EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosDxe.c
new file mode 100644
index 0000000000..0d4c90c335
--- /dev/null
+++ b/EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosDxe.c
@@ -0,0 +1,291 @@
+/** @file
+ HII-to-Redfish Bios example driver.
+
+ (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Hii2RedfishBiosDxe.h"
+
+EFI_GUID mHii2RedfishBiosGuid =
HII_2_REDFISH_BIOS_FORMSET_GUID;
+EFI_HII_HANDLE mHiiHandle;
+EFI_HANDLE DriverHandle;
+CHAR16 Hii2RedfishEfiVar[] = L"Hii2RedfishBiosEfiVar";
+
+///
+/// HII specific Vendor Device Path definition.
+///
+HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ {
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
+ (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+ }
+ },
+ HII_2_REDFISH_BIOS_FORMSET_GUID
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ (UINT8) (END_DEVICE_PATH_LENGTH),
+ (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
+ }
+ }
+};
+
+/**
+ Initial HII variable if it does not exist.
+
+ @retval EFI_SUCESS HII variable is initialized.
+
+**/
+EFI_STATUS
+InitialHiiVairable (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ HII_2_REDFISH_BIOS_EFI_VARSTORE_DATA Hii2RedfishBiosVar;
+
+ //
+ // Get Buffer Storage data from EFI variable.
+ // Try to get the current setting from variable.
+ //
+ BufferSize = sizeof (HII_2_REDFISH_BIOS_EFI_VARSTORE_DATA);
+ Status = gRT->GetVariable (
+ Hii2RedfishEfiVar,
+ &gHii2RedfishBiosFormsetGuid,
+ NULL,
+ &BufferSize,
+ &Hii2RedfishBiosVar
+ );
+ if (!EFI_ERROR (Status)) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Initialization
+ //
+ Hii2RedfishBiosVar.RefishBiosOption1Data =
STR_BIOS_OPTION_1_ITEM_1;
+ StrCpyS (Hii2RedfishBiosVar.RefishBiosOption2Data,
+ ID_STRING_MAX_WITH_TERMINATOR, L"Default");
+ Hii2RedfishBiosVar.RefishBiosOption3Data = 5;
+ Hii2RedfishBiosVar.RefishBiosOption4Data = TRUE;
+
+ Status = gRT->SetVariable (
+ Hii2RedfishEfiVar,
+ &gHii2RedfishBiosFormsetGuid,
+ VARIABLE_ATTRIBUTE_NV_BS,
+ BufferSize,
+ &Hii2RedfishBiosVar
+ );
+
+ return Status;
+}
+
+/**
+ This function allows a caller to extract the current configuration
+for one
+ or more named elements from the target driver.
+
+ @param[in] This Points to the
EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ @param[in] Request A null-terminated Unicode string in
+ <ConfigRequest> format.
+ @param[out] Progress On return, points to a character in the Request
+ string. Points to the string's null terminator if
+ request was successful. Points to the most recent
+ '&' before the first failing name/value pair (or
+ the beginning of the string if the failure is in
+ the first name/value pair) if the request was not
+ successful.
+ @param[out] Results A null-terminated Unicode string in
+ <ConfigAltResp> format which has all values filled
+ in for the names in the Request string. String to
+ be allocated by the called function.
+
+ @retval EFI_SUCCESS The Results is filled with the requested values.
+ @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
results.
+ @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown
name.
+ @retval EFI_NOT_FOUND Routing data doesn't match any storage in
this
+ driver.
+
+**/
+EFI_STATUS
+EFIAPI
+Hii2RedfishBiosExtractConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Request,
+ OUT EFI_STRING *Progress,
+ OUT EFI_STRING *Results
+ )
+{
+ if (Progress == NULL || Results == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Request == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Check whether request for EFI Varstore. EFI varstore get data //
+ through hii database, not support in this path.
+ //
+ if (HiiIsConfigHdrMatch(Request, &gHii2RedfishBiosFormsetGuid,
L"Hii2RedfishBiosEfiVar")) {
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+/**
+ This function processes the results of changes in configuration.
+
+ @param[in] This Points to the
EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ @param[in] Configuration A null-terminated Unicode string in
<ConfigResp>
+ format.
+ @param[out] Progress A pointer to a string filled in with the offset of
+ the most recent '&' before the first failing
+ name/value pair (or the beginning of the string if
+ the failure is in the first name/value pair) or
+ the terminating NULL if all was successful.
+
+ @retval EFI_SUCCESS The Results is processed successfully.
+ @retval EFI_INVALID_PARAMETER Configuration is NULL.
+ @retval EFI_NOT_FOUND Routing data doesn't match any storage in
this
+ driver.
+
+**/
+EFI_STATUS
+EFIAPI
+Hii2RedfishBiosRouteConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Configuration,
+ OUT EFI_STRING *Progress
+ )
+{
+ DEBUG ((DEBUG_INFO, "%a, unsupported\n", __FUNCTION__));
+
+ return EFI_UNSUPPORTED;
+}
+
+
+/**
+ This function processes the results of changes in configuration.
+
+ @param[in] This Points to the
EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ @param[in] Action Specifies the type of action taken by the browser.
+ @param[in] QuestionId A unique value which is sent to the original
+ exporting driver so that it can identify the type
+ of data to expect.
+ @param[in] Type The type of value for the question.
+ @param[in] Value A pointer to the data being sent to the original
+ exporting driver.
+ @param[out] ActionRequest On return, points to the action requested
by the
+ callback function.
+
+ @retval EFI_SUCCESS The callback successfully handled the action.
+ @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold
the
+ variable and its data.
+ @retval EFI_DEVICE_ERROR The variable could not be saved.
+ @retval EFI_UNSUPPORTED The specified Action is not supported by
the
+ callback.
+
+**/
+EFI_STATUS
+EFIAPI
+Hii2RedfishBiosDriverCallback (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN EFI_BROWSER_ACTION Action,
+ IN EFI_QUESTION_ID QuestionId,
+ IN UINT8 Type,
+ IN EFI_IFR_TYPE_VALUE *Value,
+ OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
+ )
+{
+ DEBUG ((DEBUG_INFO, "%a, action: 0x%x QID: 0x%x\n", __FUNCTION__,
+Action, QuestionId));
+
+ return EFI_UNSUPPORTED;
+}
+
+EFI_HII_CONFIG_ACCESS_PROTOCOL mHii2RedfishConfigAccess = {
+ Hii2RedfishBiosExtractConfig,
+ Hii2RedfishBiosRouteConfig,
+ Hii2RedfishBiosDriverCallback
+};
+
+/**
+ Main entry for this driver.
+
+ @param[in] ImageHandle Image handle this driver.
+ @param[in] SystemTable Pointer to SystemTable.
+
+ @retval EFI_SUCESS This function always complete successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+Hii2RedfishBiosDxeDriverEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ DriverHandle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &DriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &mHiiVendorDevicePath,
+ &gEfiHiiConfigAccessProtocolGuid,
+ &mHii2RedfishConfigAccess,
+ NULL
+ );
+
+ //
+ // Publish our HII data
+ //
+ mHiiHandle = HiiAddPackages (
+ &mHii2RedfishBiosGuid,
+ DriverHandle,
+ Hii2RedfishBiosDxeStrings,
+ Hii2RedfishBiosVfrBin,
+ NULL
+ );
+ if (mHiiHandle == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = InitialHiiVairable ();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to initial variable: %r\n",
+ __FUNCTION__, Status)); }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Unloads the application and its installed protocol.
+
+ @param[in] ImageHandle Handle that identifies the image to be
unloaded.
+
+ @retval EFI_SUCCESS The image has been unloaded.
+**/
+EFI_STATUS
+EFIAPI
+Hii2RedfishBiosDxeDriverUnload (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ if (mHiiHandle != NULL) {
+ HiiRemovePackages (mHiiHandle);
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosDxe.h
b/EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosDxe.h
new file mode 100644
index 0000000000..b7f9aceeb0
--- /dev/null
+++ b/EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosDxe.h
@@ -0,0 +1,44 @@
+/** @file
+ HII-to-Redfish BIOS example driver header file.
+
+ (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef HII_2_REDFISH_BIOS_DXE_H_
+#define HII_2_REDFISH_BIOS_DXE_H_
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h> #include
+<Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/PrintLib.h>
+#include <Library/HiiLib.h>
+#include <Library/DevicePathLib.h>
+
+#include <Protocol/HiiConfigAccess.h>
+#include <Guid/VariableFormat.h>
+
+#include "Hii2RedfishBiosData.h"
+
+extern UINT8 Hii2RedfishBiosVfrBin[];
+
+#pragma pack(1)
+
+///
+/// HII specific Vendor Device Path definition.
+///
+typedef struct {
+ VENDOR_DEVICE_PATH VendorDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} HII_VENDOR_DEVICE_PATH;
+
+#pragma pack()
+
+#endif
diff --git a/EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosDxe.inf
b/EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosDxe.inf
new file mode 100644
index 0000000000..06080113a1
--- /dev/null
+++ b/EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosDxe.inf
@@ -0,0 +1,55 @@
+## @file
+# HII-to-Redfish BIOS Example driver.
+#
+# (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR> # #
+SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = Hii2RedfishBiosDxe
+ FILE_GUID = 9A7FA287-4038-CB66-DC70-92AE8C0FCF73
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = Hii2RedfishBiosDxeDriverEntryPoint
+ UNLOAD_IMAGE = Hii2RedfishBiosDxeDriverUnload
+
+[Sources]
+ Hii2RedfishBiosDxe.c
+ Hii2RedfishBiosDxe.h
+ Hii2RedfishBiosData.h
+ Hii2RedfishBiosVfr.vfr
+ Hii2RedfishBiosDxeStrings.uni
+ Hii2RedfishBiosDxeMap.uni
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmulatorPkg/EmulatorPkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ PcdLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+ UefiLib
+ PrintLib
+ HiiLib
+
+[Protocols]
+ gEfiDevicePathProtocolGuid
+ gEfiHiiConfigAccessProtocolGuid
+
+
+[Guids]
+ gHii2RedfishBiosFormsetGuid
+
+[Depex]
+ gEfiHiiDatabaseProtocolGuid
+
diff --git a/EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosDxeMap.uni
b/EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosDxeMap.uni
new file mode 100644
index 0000000000..51d6d7ecb8
--- /dev/null
+++ b/EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosDxeMap.uni
@@ -0,0 +1,20 @@
+/** @file
+ HII-to-Redfish BIOS example driver.
+
+ (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/=#
+#langdef x-uefi-redfish-Bios.v1_0_9 "Bios.v1_0_9"
+
+#string STR_BIOS_OPTION_1_PROMPT #language x-uefi-redfish-
Bios.v1_0_9 "/Bios/Attributes/BiosOption1"
+#string STR_BIOS_OPTION_2_PROMPT #language x-uefi-redfish-
Bios.v1_0_9 "/Bios/Attributes/BiosOption2"
+#string STR_BIOS_OPTION_3_PROMPT #language x-uefi-redfish-
Bios.v1_0_9 "/Bios/Attributes/BiosOption3"
+#string STR_BIOS_OPTION_4_PROMPT #language x-uefi-redfish-
Bios.v1_0_9 "/Bios/Attributes/BiosOption4"
+
+#string STR_BIOS_OPTION_1_ITEM_1 #language x-uefi-redfish-
Bios.v1_0_9 "Item #1"
+#string STR_BIOS_OPTION_1_ITEM_2 #language x-uefi-redfish-
Bios.v1_0_9 "Item #2"
+#string STR_BIOS_OPTION_1_ITEM_3 #language x-uefi-redfish-
Bios.v1_0_9 "Item #3"
diff --git a/EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosDxeStrings.uni
b/EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosDxeStrings.uni
new file mode 100644
index 0000000000..84311e72a4
--- /dev/null
+++ b/EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosDxeStrings.uni
@@ -0,0 +1,30 @@
+#string /** @file
+ HII-to-Redfish BIOS example driver.
+
+ (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/=#
+#langdef en-US "English"
+
+#string STR_FORM_SET_TITLE #language en-US "HII to Redfish
(BIOS)"
+#string STR_FORM_SET_TITLE_HELP #language en-US "HII to
Redfish (BIOS)"
+#string STR_FORM_TITLE #language en-US "HII to Redfish
BIOS properties"
+
+#string STR_BIOS_OPTION_1_PROMPT #language en-US "HII
Redfish BIOS Option 1"
+#string STR_BIOS_OPTION_2_PROMPT #language en-US "HII
Redfish BIOS Option 2"
+#string STR_BIOS_OPTION_3_PROMPT #language en-US "HII
Redfish BIOS Option 3"
+#string STR_BIOS_OPTION_4_PROMPT #language en-US "HII
Redfish BIOS Option 4"
+
+#string STR_BIOS_OPTION_1_HELP #language en-US "HII Redfish
BIOS Option 1"
+#string STR_BIOS_OPTION_2_HELP #language en-US "HII Redfish
BIOS Option 2"
+#string STR_BIOS_OPTION_3_HELP #language en-US "HII Redfish
BIOS Option 3"
+#string STR_BIOS_OPTION_4_HELP #language en-US "HII Redfish
BIOS Option 4"
+
+#string STR_BIOS_OPTION_1_ITEM_1 #language en-US "Item #1"
+#string STR_BIOS_OPTION_1_ITEM_2 #language en-US "Item #2"
+#string STR_BIOS_OPTION_1_ITEM_3 #language en-US "Item #3"
+
diff --git a/EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosVfr.vfr
b/EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosVfr.vfr
new file mode 100644
index 0000000000..896feda541
--- /dev/null
+++ b/EmulatorPkg/Hii2RedfishBiosDxe/Hii2RedfishBiosVfr.vfr
@@ -0,0 +1,67 @@
+/** @file
+ HII-to-Redfish BIOS example driver VFR file.
+
+ (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include "Hii2RedfishBiosData.h"
+
+formset
+ guid = HII_2_REDFISH_BIOS_FORMSET_GUID,
+ title = STRING_TOKEN(STR_FORM_SET_TITLE),
+ help = STRING_TOKEN(STR_FORM_SET_TITLE_HELP),
+ classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID,
+
+ //
+ // Define a EFI variable Storage (EFI_IFR_VARSTORE_EFI) //
+ efivarstore HII_2_REDFISH_BIOS_EFI_VARSTORE_DATA,
+ attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS |
EFI_VARIABLE_NON_VOLATILE, // EFI variable attribures
+ name = Hii2RedfishBiosEfiVar,
+ guid = HII_2_REDFISH_BIOS_FORMSET_GUID;
+
+ //
+ // Define a Form (EFI_IFR_FORM)
+ //
+ form formid = FORM_ID, // Form ID
+ title = STRING_TOKEN(STR_FORM_TITLE); // Form title
+
+ oneof varid = Hii2RedfishBiosEfiVar.RefishBiosOption1Data,
+ questionid = FROM_ID_BIOS_OPTION_1,
+ prompt = STRING_TOKEN(STR_BIOS_OPTION_1_PROMPT),
+ help = STRING_TOKEN(STR_BIOS_OPTION_1_HELP),
+ flags = INTERACTIVE | NUMERIC_SIZE_1,
+ option text = STRING_TOKEN(STR_BIOS_OPTION_1_ITEM_1), value
= STR_BIOS_OPTION_1_ITEM_1, flags = DEFAULT;
+ option text = STRING_TOKEN(STR_BIOS_OPTION_1_ITEM_2), value
= STR_BIOS_OPTION_1_ITEM_2, flags = 0;
+ option text = STRING_TOKEN(STR_BIOS_OPTION_1_ITEM_3), value
= STR_BIOS_OPTION_1_ITEM_3, flags = 0;
+ endoneof;
+
+ string varid = Hii2RedfishBiosEfiVar.RefishBiosOption2Data,
+ prompt = STRING_TOKEN(STR_BIOS_OPTION_2_PROMPT),
+ help = STRING_TOKEN(STR_BIOS_OPTION_2_HELP),
+ flags = READ_ONLY,
+ minsize = ID_STRING_MIN,
+ maxsize = ID_STRING_MAX,
+ endstring;
+
+ numeric varid = Hii2RedfishBiosEfiVar.RefishBiosOption3Data,
+ prompt = STRING_TOKEN(STR_BIOS_OPTION_3_PROMPT),
+ help = STRING_TOKEN(STR_BIOS_OPTION_3_HELP),
+ minimum = 0,
+ maximum = 0xff,
+ step = 1,
+ default = 20,
+ endnumeric;
+
+ checkbox varid = Hii2RedfishBiosEfiVar.RefishBiosOption4Data,
+ prompt = STRING_TOKEN(STR_BIOS_OPTION_4_PROMPT),
+ help = STRING_TOKEN(STR_BIOS_OPTION_4_PROMPT),
+ flags = CHECKBOX_DEFAULT,
+ default = TRUE,
+ endcheckbox;
+ endform;
+endformset;
--
2.32.0.windows.2


Re: [edk2-staging][PATCH v2 1/2] edk2-staging/EmulatorPkg: Introduce Hii2RedfishBootDxe driver

Chang, Abner
 

[AMD Official Use Only - General]

Reviewed-by: Abner Chang <abner.chang@...>

-----Original Message-----
From: Nickle Wang <nickle.wang@...>
Sent: Monday, July 25, 2022 9:36 AM
To: devel@edk2.groups.io
Cc: Andrew Fish <afish@...>; Ray Ni <ray.ni@...>; Chang,
Abner <Abner.Chang@...>; Yang, Atom <Atom.Yang@...>;
Nick Ramirez <nramirez@...>
Subject: [edk2-staging][PATCH v2 1/2] edk2-staging/EmulatorPkg: Introduce
Hii2RedfishBootDxe driver

[CAUTION: External Email]

Add Hii2RedfishBootDxe driver with configure language defined in UNI file in
order to demonstrate the use of Redfish Platform Config Protocol. Feature
drivers under RedfishClientPkg will work with this driver and provide the
REST data to Redfish service.

Signed-off-by: Nickle Wang <nickle.wang@...>
Cc: Andrew Fish <afish@...>
Cc: Ray Ni <ray.ni@...>
Cc: Abner Chang <abner.chang@...>
Cc: Yang Atom <Atom.Yang@...>
Cc: Nick Ramirez <nramirez@...>
---
EmulatorPkg/EmulatorPkg.dec | 5 +-
EmulatorPkg/EmulatorPkg.dsc | 3 +-
EmulatorPkg/EmulatorPkg.fdf | 3 +-
.../Hii2RedfishBootDxe/Hii2RedfishBootData.h | 60 ++
.../Hii2RedfishBootDxe/Hii2RedfishBootDxe.c | 702 ++++++++++++++++++
.../Hii2RedfishBootDxe/Hii2RedfishBootDxe.h | 53 ++
.../Hii2RedfishBootDxe/Hii2RedfishBootDxe.inf | 60 ++
.../Hii2RedfishBootDxeMap.uni | 28 +
.../Hii2RedfishBootDxeStrings.uni | 41 +
.../Hii2RedfishBootDxe/Hii2RedfishBootVfr.vfr | 83 +++
10 files changed, 1034 insertions(+), 4 deletions(-) create mode 100644
EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootData.h
create mode 100644 EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootDxe.c
create mode 100644
EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootDxe.h
create mode 100644
EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootDxe.inf
create mode 100644
EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootDxeMap.uni
create mode 100644
EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootDxeStrings.uni
create mode 100644
EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootVfr.vfr

diff --git a/EmulatorPkg/EmulatorPkg.dec b/EmulatorPkg/EmulatorPkg.dec
index 9e87b50afc..52a62c09c9 100644
--- a/EmulatorPkg/EmulatorPkg.dec
+++ b/EmulatorPkg/EmulatorPkg.dec
@@ -4,7 +4,7 @@
#
# Copyright (c) 2008 - 2019, Intel Corporation. All rights reserved.<BR> #
Portions copyright (c) 2011, Apple Inc. All rights reserved.
-# (C) Copyright 2020-2021 Hewlett Packard Enterprise Development LP<BR>
+# (C) Copyright 2020-2022 Hewlett Packard Enterprise Development LP<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -47,7 +47,8 @@
gEmuVirtualDisksGuid = { 0xf2ba331a, 0x8985, 0x11db, { 0xa4, 0x06, 0x00,
0x40, 0xd0, 0x2b, 0x18, 0x35 } }
gEmuPhysicalDisksGuid = { 0xf2bdcc96, 0x8985, 0x11db, { 0x87, 0x19, 0x00,
0x40, 0xd0, 0x2b, 0x18, 0x35 } }
gEmuRedfishServiceGuid = { 0x3fb208ac, 0x2185, 0x498c, { 0xbf, 0x46,
0xdc, 0x23, 0xda, 0x58, 0x7b, 0x55 } }
- gHii2RedfishMemoryFormsetGuid = { 0XC2BE579E, 0X3C57, 0X499C, { 0XA9,
0XDF, 0XE6, 0X23, 0X8A, 0X49, 0X64, 0XF8 }}
+ gHii2RedfishMemoryFormsetGuid = { 0xC2BE579E, 0x3C57, 0x499C, {
+ 0xA9, 0xDF, 0xE6, 0x23, 0x8A, 0x49, 0x64, 0xF8 }}
+ gHii2RedfishBootFormsetGuid = { 0x8399a787, 0x108e, 0x4e53, { 0x9e,
+ 0xde, 0x4b, 0x18, 0xcc, 0x9e, 0xab, 0x3b }}

[PcdsFeatureFlag]
## If TRUE, if symbols only load on breakpoints and gdb entry diff --git
a/EmulatorPkg/EmulatorPkg.dsc b/EmulatorPkg/EmulatorPkg.dsc index
e5cb3c3d8d..1d59b4a1dd 100644
--- a/EmulatorPkg/EmulatorPkg.dsc
+++ b/EmulatorPkg/EmulatorPkg.dsc
@@ -7,7 +7,7 @@
# Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR> #
Portions copyright (c) 2010 - 2011, Apple Inc. All rights reserved.<BR> #
Copyright (c) Microsoft Corporation.
-# (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
+# (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -490,6 +490,7 @@

!if $(REDFISH_ENABLE) == TRUE
EmulatorPkg/Hii2RedfishMemoryDxe/Hii2RedfishMemoryDxe.inf
+ EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootDxe.inf
!endif
!include RedfishPkg/Redfish.dsc.inc
!include RedfishClientPkg/RedfishClient.dsc.inc
diff --git a/EmulatorPkg/EmulatorPkg.fdf b/EmulatorPkg/EmulatorPkg.fdf
index 5e770af186..f9ff4320d9 100644
--- a/EmulatorPkg/EmulatorPkg.fdf
+++ b/EmulatorPkg/EmulatorPkg.fdf
@@ -3,7 +3,7 @@
#
# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR> #
Portions copyright (c) 2009 - 2011, Apple Inc. All rights reserved.<BR> -# (C)
Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
+# (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -214,6 +214,7 @@
INF EmulatorPkg/EmuSnpDxe/EmuSnpDxe.inf
#
!if $(REDFISH_ENABLE) == TRUE
INF EmulatorPkg/Hii2RedfishMemoryDxe/Hii2RedfishMemoryDxe.inf
+ INF EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootDxe.inf
!endif
!include RedfishPkg/Redfish.fdf.inc
!include RedfishClientPkg/RedfishClient.fdf.inc
diff --git a/EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootData.h
b/EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootData.h
new file mode 100644
index 0000000000..0da28a5032
--- /dev/null
+++ b/EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootData.h
@@ -0,0 +1,60 @@
+/** @file
+ The header file of HII-to-Redfish boot driver.
+
+ (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef HII_2_REDFISH_BOOT_DATA_H_
+#define HII_2_REDFISH_BOOT_DATA_H_
+
+#include <Uefi/UefiMultiPhase.h>
+#include <Guid/HiiPlatformSetupFormset.h>
+
+#define HII_2_REDFISH_BOOT_FORMSET_GUID \
+ { \
+ 0x8399a787, 0x108e, 0x4e53, { 0x9e, 0xde, 0x4b, 0x18, 0xcc, 0x9e,
+0xab, 0x3b } \
+ }
+
+extern EFI_GUID gHii2RedfishBootFormsetGuid;
+
+#define FORM_ID 0x001
+#define QUESTION_ID_BOOT_SOURCE_OVERRIDE_ENABLED 0x100
+#define QUESTION_ID_BOOT_SOURCE_OVERRIDE_MODE 0x101
+#define QUESTION_ID_BOOT_SOURCE_OVERRIDE_TARGET 0x102
+#define LABEL_BOOT_OPTION 0x200
+#define LABEL_BOOT_OPTION_END 0x201
+#define BOOT_ORDER_LIST 0x300
+#define MAX_BOOT_OPTIONS 100
+#define BOOT_OPTION_VAR_STORE_ID 0x800
+//
+// VarOffset that will be used to create question // all these values
+are computed from the structure // defined below //
+#define VAR_OFFSET(Field) ((UINT16) ((UINTN)
&(((HII_2_REDFISH_BOOT_OPTION_VARSTORE_DATA *) 0)->Field)))
+
+#pragma pack(1)
+
+//
+// Definiton of HII_2_REDFISH_BOOT_EFI_VARSTORE_DATA
+//
+typedef struct {
+ UINT8 BootSourceOverrideEnabled;
+ UINT8 BootSourceOverrideMode;
+ UINT8 BootSourceOverrideTarget;
+ UINT8 Reversed;
+} HII_2_REDFISH_BOOT_EFI_VARSTORE_DATA;
+
+//
+// Definiton of HII_2_REDFISH_BOOT_OPTION_VARSTORE_DATA
+//
+typedef struct {
+ UINT32 BootOptionOrder[MAX_BOOT_OPTIONS];
+} HII_2_REDFISH_BOOT_OPTION_VARSTORE_DATA;
+
+#pragma pack()
+
+#endif
diff --git a/EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootDxe.c
b/EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootDxe.c
new file mode 100644
index 0000000000..203fd8e1ef
--- /dev/null
+++ b/EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootDxe.c
@@ -0,0 +1,702 @@
+/** @file
+ HII-to-Redfish boot driver.
+
+ (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Hii2RedfishBootDxe.h"
+
+EFI_GUID mHii2RedfishBootGuid =
HII_2_REDFISH_BOOT_FORMSET_GUID;
+EFI_HII_HANDLE mHiiHandle;
+EFI_HANDLE mDriverHandle;
+EFI_EVENT mEvent = NULL;
+CHAR16 mHii2RedfishEfiVar[] = L"Hii2RedfishBootEfiVar";
+HII_2_REDFISH_BOOT_OPTION_VARSTORE_DATA mBootOptionsVarData;
+
+///
+/// HII specific Vendor Device Path definition.
+///
+HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ {
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
+ (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+ }
+ },
+ HII_2_REDFISH_BOOT_FORMSET_GUID
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ (UINT8) (END_DEVICE_PATH_LENGTH),
+ (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
+ }
+ }
+};
+
+/**
+ This function add 'x-uefi-' configuration language to given string ID.
+
+ @param[in] HiiHandle HII handle
+ @param[in] StringId String token ID
+ @param[in] ConfigLang Configure language of question
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+UpdateConfigLanguageToQuestion (
+ IN EFI_HII_HANDLE HiiHandle,
+ IN EFI_STRING_ID StringId,
+ IN EFI_STRING ConfigLang
+ )
+{
+ CHAR16 ConfigLanguage[32];
+
+ if (HiiHandle == NULL || StringId == 0 || ConfigLang == NULL) {
+ return EFI_INVALID_LANGUAGE;
+ }
+
+ UnicodeSPrint (ConfigLanguage, sizeof (ConfigLanguage), ConfigLang);
+
+ DEBUG ((DEBUG_INFO, "%a, add config-language for string(%d): %s\n",
+ __FUNCTION__, StringId, ConfigLanguage));
+
+ HiiSetString (
+ HiiHandle,
+ StringId,
+ ConfigLanguage,
+ COMPUTER_SYSTEM_SECHEMA_VERSION
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function add 'x-uefi-' configuration language to given string ID.
+
+ @param[in] HiiHandle HII handle
+ @param[in] StringId String token ID
+ @param[in] Index The index of boot option
+ @param[in] BootOption Boot option context
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+UpdateConfigLanguageToValues (
+ IN EFI_HII_HANDLE HiiHandle,
+ IN EFI_STRING_ID StringId,
+ IN UINTN Index,
+ IN EFI_BOOT_MANAGER_LOAD_OPTION *BootOption
+ )
+{
+ CHAR16 ConfigLanguage[10];
+
+ if (HiiHandle == NULL || StringId == 0 || BootOption == NULL) {
+ return EFI_INVALID_LANGUAGE;
+ }
+
+ UnicodeSPrint (ConfigLanguage, sizeof (ConfigLanguage), L"Boot%04x",
+ BootOption->OptionNumber);
+
+ DEBUG ((DEBUG_INFO, "%a, add config-language for string(%d): %s\n",
+ __FUNCTION__, StringId, ConfigLanguage));
+
+ HiiSetString (
+ HiiHandle,
+ StringId,
+ ConfigLanguage,
+ COMPUTER_SYSTEM_SECHEMA_VERSION
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function creates boot order with ordered-list op-codes in runtime.
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+RefreshBootOrderList (
+ VOID
+ )
+{
+ UINTN Index;
+ EFI_BOOT_MANAGER_LOAD_OPTION *BootOption;
+ UINTN BootOptionCount;
+ EFI_STRING_ID Token;
+ VOID *StartOpCodeHandle;
+ VOID *EndOpCodeHandle;
+ EFI_IFR_GUID_LABEL *StartLabel;
+ EFI_IFR_GUID_LABEL *EndLabel;
+ BOOLEAN IsLegacyOption;
+ VOID *OptionsOpCodeHandle;
+ UINTN OptionIndex;
+
+ //
+ // for better user experience
+ // 1. User changes HD configuration (e.g.: unplug HDD), here we have
+ a chance to remove the HDD boot option // 2. User enables/disables
+ UEFI PXE, here we have a chance to add/remove EFI Network boot option
+ // EfiBootManagerRefreshAllBootOption ();
+
+ BootOption = EfiBootManagerGetLoadOptions (&BootOptionCount,
+ LoadOptionTypeBoot);
+
+ if (BootOptionCount == 0) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Initial var store
+ //
+ ZeroMem (&mBootOptionsVarData, sizeof
+ (HII_2_REDFISH_BOOT_OPTION_VARSTORE_DATA));
+
+ //
+ // Allocate space for creation of UpdateData Buffer //
+ StartOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT
+ (StartOpCodeHandle != NULL);
+
+ EndOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT
+ (EndOpCodeHandle != NULL);
+
+ //
+ // Create Hii Extend Label OpCode as the start opcode // StartLabel
+ = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle,
+ &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); StartLabel-
ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ StartLabel->Number = LABEL_BOOT_OPTION;
+
+ //
+ // Create Hii Extend Label OpCode as the end opcode // EndLabel =
+ (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle,
+ &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); EndLabel-
ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ EndLabel->Number = LABEL_BOOT_OPTION_END;
+
+
+ OptionsOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT
+ (OptionsOpCodeHandle != NULL);
+
+ for (Index = 0, OptionIndex = 0; Index < BootOptionCount; Index++) {
+ //
+ // Don't display hidden boot options, but retain inactive ones.
+ //
+ if ((BootOption[Index].Attributes & LOAD_OPTION_HIDDEN) != 0) {
+ continue;
+ }
+
+ //
+ // Group the legacy boot option in the sub title created dynamically
+ //
+ IsLegacyOption = (BOOLEAN) (
+ (DevicePathType (BootOption[Index].FilePath) ==
BBS_DEVICE_PATH) &&
+ (DevicePathSubType (BootOption[Index].FilePath) ==
BBS_BBS_DP)
+ );
+
+ //
+ // Don't display legacy boot options
+ //
+ if (IsLegacyOption) {
+ continue;
+ }
+
+ mBootOptionsVarData.BootOptionOrder[OptionIndex++] =
+ (UINT32)BootOption[Index].OptionNumber;
+
+ ASSERT (BootOption[Index].Description != NULL);
+
+ Token = HiiSetString (mHiiHandle, 0, BootOption[Index].Description,
+ NULL);
+
+ //
+ // Add boot option
+ //
+ HiiCreateOneOfOptionOpCode (
+ OptionsOpCodeHandle,
+ Token,
+ 0,
+ EFI_IFR_TYPE_NUM_SIZE_32,
+ BootOption[Index].OptionNumber
+ );
+
+ //
+ // Add x-uefi configure language for boot options.
+ //
+ UpdateConfigLanguageToValues (mHiiHandle, Token, OptionIndex,
+ &BootOption[Index]); }
+
+ //
+ // Create ordered list op-code
+ //
+ HiiCreateOrderedListOpCode (
+ StartOpCodeHandle, // Container for dynamic created
opcodes
+ BOOT_ORDER_LIST, // Question ID
+ BOOT_OPTION_VAR_STORE_ID, // VarStore ID
+ (UINT16)VAR_OFFSET (BootOptionOrder), // Offset in Buffer
Storage
+ STRING_TOKEN (STR_BOOT_ORDER_LIST), // Question prompt text
+ STRING_TOKEN (STR_BOOT_ORDER_LIST_HELP), // Question help text
+ 0, // Question flag
+ EFI_IFR_UNIQUE_SET, // Ordered list flag, e.g.
EFI_IFR_UNIQUE_SET
+ EFI_IFR_TYPE_NUM_SIZE_32, // Data type of Question value
+ MAX_BOOT_OPTIONS, // Maximum container
+ OptionsOpCodeHandle, // Option Opcode list
+ NULL // Default Opcode is NULL
+ );
+
+ //
+ // Add x-uefi configure language for boot order.
+ //
+ UpdateConfigLanguageToQuestion (mHiiHandle, STRING_TOKEN
+ (STR_BOOT_ORDER_LIST), COMPUTER_SYSTEM_BOOT_BOOTORDER);
+
+ //
+ // Update HII form
+ //
+ HiiUpdateForm (
+ mHiiHandle,
+ &mHii2RedfishBootGuid,
+ FORM_ID,
+ StartOpCodeHandle,
+ EndOpCodeHandle
+ );
+
+ HiiFreeOpCodeHandle (StartOpCodeHandle); HiiFreeOpCodeHandle
+ (EndOpCodeHandle); HiiFreeOpCodeHandle (OptionsOpCodeHandle);
+
+ EfiBootManagerFreeLoadOptions (BootOption, BootOptionCount);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function update the "BootOrder" EFI Variable based on
+ BMM Formset's NV map. It then refresh BootOptionMenu
+ with the new "BootOrder" list.
+
+ @param[in] BootOptionVar Boot option NV data
+
+ @retval EFI_SUCCESS The function complete successfully.
+ @retval EFI_OUT_OF_RESOURCES Not enough memory to complete the
function.
+ @return The EFI variable can not be saved. See gRT->SetVariable for detail
return information.
+
+**/
+EFI_STATUS
+UpdateBootorderList (
+ IN HII_2_REDFISH_BOOT_OPTION_VARSTORE_DATA *BootOptionVar
+ )
+{
+ EFI_STATUS Status;
+ UINT16 Index;
+ UINT16 OrderIndex;
+ UINT16 *BootOrder;
+ UINTN BootOrderSize;
+ UINT16 OptionNumber;
+
+ if (BootOptionVar == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // First check whether BootOrder is present in current configuration
+ //
+ GetEfiGlobalVariable2 (L"BootOrder", (VOID **) &BootOrder,
+ &BootOrderSize); if (BootOrder == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // OptionOrder is subset of BootOrder // for (OrderIndex = 0;
+ (OrderIndex < MAX_BOOT_OPTIONS) && (BootOptionVar-
BootOptionOrder[OrderIndex] != 0); OrderIndex++) {
+ for (Index = OrderIndex; Index < BootOrderSize / sizeof (UINT16);
Index++) {
+ if ((BootOrder[Index] == (UINT16)BootOptionVar-
BootOptionOrder[OrderIndex]) && (OrderIndex != Index)) {
+ OptionNumber = BootOrder[Index];
+ CopyMem (&BootOrder[OrderIndex + 1], &BootOrder[OrderIndex],
(Index - OrderIndex) * sizeof (UINT16));
+ BootOrder[OrderIndex] = OptionNumber;
+ }
+ }
+ }
+
+ Status = gRT->SetVariable (
+ L"BootOrder",
+ &gEfiGlobalVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ BootOrderSize,
+ BootOrder
+ );
+ FreePool (BootOrder);
+
+ return Status;
+}
+
+/**
+ Initial HII variable if it does not exist.
+
+ @retval EFI_SUCESS HII variable is initialized.
+
+**/
+EFI_STATUS
+InitialHiiVairable (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ HII_2_REDFISH_BOOT_EFI_VARSTORE_DATA Hii2RedfishBootVar;
+
+ //
+ // Get Buffer Storage data from EFI variable.
+ // Try to get the current setting from variable.
+ //
+ BufferSize = sizeof (HII_2_REDFISH_BOOT_EFI_VARSTORE_DATA);
+ Status = gRT->GetVariable (
+ mHii2RedfishEfiVar,
+ &gHii2RedfishBootFormsetGuid,
+ NULL,
+ &BufferSize,
+ &Hii2RedfishBootVar
+ );
+ if (!EFI_ERROR (Status)) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Initialization
+ //
+ Hii2RedfishBootVar.BootSourceOverrideEnabled = STR_DISABLED;
+ Hii2RedfishBootVar.BootSourceOverrideMode = STR_UEFI;
+ Hii2RedfishBootVar.BootSourceOverrideTarget = STR_TARGET_NONE;
+ Hii2RedfishBootVar.Reversed = 0x00;
+
+ Status = gRT->SetVariable (
+ mHii2RedfishEfiVar,
+ &gHii2RedfishBootFormsetGuid,
+ VARIABLE_ATTRIBUTE_NV_BS,
+ BufferSize,
+ &Hii2RedfishBootVar
+ );
+
+ //
+ // Initial var store
+ //
+ ZeroMem (&mBootOptionsVarData, sizeof
+ (HII_2_REDFISH_BOOT_OPTION_VARSTORE_DATA));
+
+ return Status;
+}
+
+/**
+ This function allows a caller to extract the current configuration
+for one
+ or more named elements from the target driver.
+
+ @param[in] This Points to the
EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ @param[in] Request A null-terminated Unicode string in
+ <ConfigRequest> format.
+ @param[out] Progress On return, points to a character in the Request
+ string. Points to the string's null terminator if
+ request was successful. Points to the most recent
+ '&' before the first failing name/value pair (or
+ the beginning of the string if the failure is in
+ the first name/value pair) if the request was not
+ successful.
+ @param[out] Results A null-terminated Unicode string in
+ <ConfigAltResp> format which has all values filled
+ in for the names in the Request string. String to
+ be allocated by the called function.
+
+ @retval EFI_SUCCESS The Results is filled with the requested values.
+ @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
results.
+ @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown
name.
+ @retval EFI_NOT_FOUND Routing data doesn't match any storage in
this
+ driver.
+
+**/
+EFI_STATUS
+EFIAPI
+Hii2RedfishBootExtractConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Request,
+ OUT EFI_STRING *Progress,
+ OUT EFI_STRING *Results
+ )
+{
+ EFI_STATUS Status;
+
+ if (Progress == NULL || Results == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Progress = Request;
+
+ if (Request == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Check whether request for EFI Varstore. EFI varstore get data //
+ through hii database, not support in this path.
+ //
+ if (HiiIsConfigHdrMatch(Request, &gHii2RedfishBootFormsetGuid,
L"Hii2RedfishBootEfiVar")) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Handle boot order list
+ //
+ if (HiiIsConfigHdrMatch(Request, &gHii2RedfishBootFormsetGuid,
L"Hii2RedfishBootOptionVar")) {
+ Status = gHiiConfigRouting->BlockToConfig (
+ gHiiConfigRouting,
+ Request,
+ (UINT8 *) &mBootOptionsVarData,
+ sizeof (HII_2_REDFISH_BOOT_OPTION_VARSTORE_DATA),
+ Results,
+ Progress
+ );
+
+ //
+ // Set Progress string to the original request string.
+ //
+ if (Request == NULL) {
+ *Progress = NULL;
+ } else if (StrStr (Request, L"OFFSET") == NULL) {
+ *Progress = Request + StrLen (Request);
+ }
+
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+/**
+ This function processes the results of changes in configuration.
+
+ @param[in] This Points to the
EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ @param[in] Configuration A null-terminated Unicode string in
<ConfigResp>
+ format.
+ @param[out] Progress A pointer to a string filled in with the offset of
+ the most recent '&' before the first failing
+ name/value pair (or the beginning of the string if
+ the failure is in the first name/value pair) or
+ the terminating NULL if all was successful.
+
+ @retval EFI_SUCCESS The Results is processed successfully.
+ @retval EFI_INVALID_PARAMETER Configuration is NULL.
+ @retval EFI_NOT_FOUND Routing data doesn't match any storage in
this
+ driver.
+
+**/
+EFI_STATUS
+EFIAPI
+Hii2RedfishBootRouteConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Configuration,
+ OUT EFI_STRING *Progress
+ )
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ HII_2_REDFISH_BOOT_OPTION_VARSTORE_DATA BootOptionsVar;
+
+ *Progress = Configuration;
+
+ //
+ // Check whether request for EFI Varstore. EFI varstore get data //
+ through hii database, not support in this path.
+ //
+ if (HiiIsConfigHdrMatch(Configuration, &gHii2RedfishBootFormsetGuid,
L"Hii2RedfishBootEfiVar")) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Handle boot order list
+ //
+ if (HiiIsConfigHdrMatch(Configuration, &gHii2RedfishBootFormsetGuid,
L"Hii2RedfishBootOptionVar")) {
+ BufferSize = sizeof(HII_2_REDFISH_BOOT_OPTION_VARSTORE_DATA);
+ ZeroMem (&BootOptionsVar,
sizeof(HII_2_REDFISH_BOOT_OPTION_VARSTORE_DATA));
+ Status = gHiiConfigRouting->ConfigToBlock (
+ gHiiConfigRouting,
+ Configuration,
+ (UINT8 *)&BootOptionsVar,
+ &BufferSize,
+ Progress
+ );
+
+ if (CompareMem (BootOptionsVar.BootOptionOrder,
mBootOptionsVarData.BootOptionOrder, (sizeof (UINT32) *
MAX_BOOT_OPTIONS))) {
+ Status = UpdateBootorderList (&BootOptionsVar);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Boot order update successed. Copy it to local copy.
+ //
+ CopyMem (mBootOptionsVarData.BootOptionOrder,
BootOptionsVar.BootOptionOrder, (sizeof (UINT32) *
MAX_BOOT_OPTIONS));
+ }
+ }
+
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+/**
+ This function processes the results of changes in configuration.
+
+ @param[in] This Points to the
EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ @param[in] Action Specifies the type of action taken by the browser.
+ @param[in] QuestionId A unique value which is sent to the original
+ exporting driver so that it can identify the type
+ of data to expect.
+ @param[in] Type The type of value for the question.
+ @param[in] Value A pointer to the data being sent to the original
+ exporting driver.
+ @param[out] ActionRequest On return, points to the action requested
by the
+ callback function.
+
+ @retval EFI_SUCCESS The callback successfully handled the action.
+ @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold
the
+ variable and its data.
+ @retval EFI_DEVICE_ERROR The variable could not be saved.
+ @retval EFI_UNSUPPORTED The specified Action is not supported by
the
+ callback.
+
+**/
+EFI_STATUS
+EFIAPI
+Hii2RedfishBootDriverCallback (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN EFI_BROWSER_ACTION Action,
+ IN EFI_QUESTION_ID QuestionId,
+ IN UINT8 Type,
+ IN EFI_IFR_TYPE_VALUE *Value,
+ OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
+ )
+{
+ DEBUG ((DEBUG_INFO, "%a, action: 0x%x QID: 0x%x\n", __FUNCTION__,
+Action, QuestionId));
+
+ if (QuestionId == QUESTION_ID_BOOT_SOURCE_OVERRIDE_ENABLED &&
Action == EFI_BROWSER_ACTION_FORM_OPEN) {
+ RefreshBootOrderList ();
+
+ return EFI_SUCCESS;
+ }
+
+ return EFI_UNSUPPORTED;
+}
+
+EFI_HII_CONFIG_ACCESS_PROTOCOL mHii2RedfishConfigAccess = {
+ Hii2RedfishBootExtractConfig,
+ Hii2RedfishBootRouteConfig,
+ Hii2RedfishBootDriverCallback
+};
+
+/**
+ Callback function executed when the ready-to-provisioning event group is
signaled.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[out] Context Pointer to the Context buffer
+
+**/
+VOID
+EFIAPI
+Hii2RedfishBootReadyToProvisioning (
+ IN EFI_EVENT Event,
+ OUT VOID *Context
+ )
+{
+ //
+ // Refresh boot order and create configure language
+ //
+ RefreshBootOrderList ();
+}
+
+/**
+ Main entry for this driver.
+
+ @param[in] ImageHandle Image handle this driver.
+ @param[in] SystemTable Pointer to SystemTable.
+
+ @retval EFI_SUCESS This function always complete successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+Hii2RedfishBootDxeDriverEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ mDriverHandle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mDriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &mHiiVendorDevicePath,
+ &gEfiHiiConfigAccessProtocolGuid,
+ &mHii2RedfishConfigAccess,
+ NULL
+ );
+
+ //
+ // Publish our HII data
+ //
+ mHiiHandle = HiiAddPackages (
+ &mHii2RedfishBootGuid,
+ mDriverHandle,
+ Hii2RedfishBootDxeStrings,
+ Hii2RedfishBootVfrBin,
+ NULL
+ );
+ if (mHiiHandle == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = InitialHiiVairable ();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to initial variable: %r\n",
+ __FUNCTION__, Status)); }
+
+ //
+ // Register read-to-provisioning event // Status =
+ CreateReadyToProvisioningEvent (
+ Hii2RedfishBootReadyToProvisioning,
+ NULL,
+ &mEvent
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to register ready-to-provisioning
+ event: %r\n", __FUNCTION__, Status)); }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Unloads the application and its installed protocol.
+
+ @param[in] ImageHandle Handle that identifies the image to be
unloaded.
+
+ @retval EFI_SUCCESS The image has been unloaded.
+**/
+EFI_STATUS
+EFIAPI
+Hii2RedfishBootDxeDriverUnload (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ if (mHiiHandle != NULL) {
+ HiiRemovePackages (mHiiHandle);
+ }
+
+ if (mEvent != NULL) {
+ gBS->CloseEvent (mEvent);
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootDxe.h
b/EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootDxe.h
new file mode 100644
index 0000000000..58e6d33f0f
--- /dev/null
+++ b/EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootDxe.h
@@ -0,0 +1,53 @@
+/** @file
+ HII-to-Redfish memory driver header file.
+
+ (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef HII_2_REDFISH_BOOT_DXE_H_
+#define HII_2_REDFISH_BOOT_DXE_H_
+
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h> #include
+<Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/PrintLib.h>
+#include <Library/HiiLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiBootManagerLib.h> #include
+<Library/UefiHiiServicesLib.h> #include <Library/RedfishEventLib.h>
+
+#include <Protocol/HiiConfigAccess.h>
+
+#include <Guid/VariableFormat.h>
+#include <Guid/MdeModuleHii.h>
+
+#include "Hii2RedfishBootData.h"
+
+extern UINT8 Hii2RedfishBootVfrBin[];
+
+#define COMPUTER_SYSTEM_SECHEMA_VERSION "x-uefi-redfish-
ComputerSystem.v1_5_0"
+#define COMPUTER_SYSTEM_BOOT_BOOTORDER
L"/Systems/{1}/Boot/BootOrder"
+
+#pragma pack(1)
+
+///
+/// HII specific Vendor Device Path definition.
+///
+typedef struct {
+ VENDOR_DEVICE_PATH VendorDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} HII_VENDOR_DEVICE_PATH;
+
+#pragma pack()
+
+#endif
diff --git a/EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootDxe.inf
b/EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootDxe.inf
new file mode 100644
index 0000000000..8d40885904
--- /dev/null
+++ b/EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootDxe.inf
@@ -0,0 +1,60 @@
+## @file
+# HII-to-Redfish boot driver.
+#
+# (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR> # #
+SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = Hii2RedfishBootDxe
+ FILE_GUID = F9BA69BD-1EDB-4334-9D57-7E974ADF1361
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = Hii2RedfishBootDxeDriverEntryPoint
+ UNLOAD_IMAGE = Hii2RedfishBootDxeDriverUnload
+
+[Sources]
+ Hii2RedfishBootDxe.c
+ Hii2RedfishBootDxe.h
+ Hii2RedfishBootData.h
+ Hii2RedfishBootVfr.vfr
+ Hii2RedfishBootDxeStrings.uni
+ Hii2RedfishBootDxeMap.uni
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmulatorPkg/EmulatorPkg.dec
+ RedfishClientPkg/RedfishClientPkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ PcdLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+ UefiLib
+ PrintLib
+ HiiLib
+ UefiBootManagerLib
+ UefiHiiServicesLib
+ RedfishEventLib
+
+[Protocols]
+ gEfiDevicePathProtocolGuid
+ gEfiHiiConfigAccessProtocolGuid
+
+
+[Guids]
+ gHii2RedfishBootFormsetGuid
+ gEfiIfrTianoGuid
+
+[Depex]
+ gEfiHiiDatabaseProtocolGuid
+
diff --git a/EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootDxeMap.uni
b/EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootDxeMap.uni
new file mode 100644
index 0000000000..0589c90df5
--- /dev/null
+++ b/EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootDxeMap.uni
@@ -0,0 +1,28 @@
+/** @file
+ HII-to-Redfish memory driver.
+
+ (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/=#
+#langdef x-uefi-redfish-ComputerSystem.v1_5_0
"ComputerSystem.v1_5_0"
+
+#string STR_BOOT_SOURCE_OVERRIDE_ENABLED #language x-uefi-
redfish-ComputerSystem.v1_5_0
"/Systems/{1}/Boot/BootSourceOverrideEnabled"
+#string STR_BOOT_SOURCE_OVERRIDE_MODE #language x-uefi-
redfish-ComputerSystem.v1_5_0
"/Systems/{1}/Boot/BootSourceOverrideMode"
+#string STR_BOOT_SOURCE_OVERRIDE_TARGET #language x-uefi-
redfish-ComputerSystem.v1_5_0
"/Systems/{1}/Boot/BootSourceOverrideTarget"
+
+#string STR_DISABLED #language x-uefi-redfish-
ComputerSystem.v1_5_0 "Disabled"
+#string STR_ONCE #language x-uefi-redfish-
ComputerSystem.v1_5_0 "Once"
+#string STR_CONTINUOUS #language x-uefi-redfish-
ComputerSystem.v1_5_0 "Continuous"
+#string STR_UEFI #language x-uefi-redfish-
ComputerSystem.v1_5_0 "UEFI"
+#string STR_LEGACY #language x-uefi-redfish-
ComputerSystem.v1_5_0 "Legacy"
+#string STR_TARGET_NONE #language x-uefi-redfish-
ComputerSystem.v1_5_0 "None"
+#string STR_TARGET_PXE #language x-uefi-redfish-
ComputerSystem.v1_5_0 "Pxe"
+#string STR_TARGET_USB #language x-uefi-redfish-
ComputerSystem.v1_5_0 "Usb"
+#string STR_TARGET_HDD #language x-uefi-redfish-
ComputerSystem.v1_5_0 "Hdd"
+#string STR_TARGET_BIOS_SETUP #language x-uefi-redfish-
ComputerSystem.v1_5_0 "BiosSetup"
+#string STR_TARGET_UEFI #language x-uefi-redfish-
ComputerSystem.v1_5_0 "UefiTarget"
+#string STR_TARGET_UEFI_HTTP #language x-uefi-redfish-
ComputerSystem.v1_5_0 "UefiHttp"
diff --git a/EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootDxeStrings.uni
b/EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootDxeStrings.uni
new file mode 100644
index 0000000000..c2057633c2
--- /dev/null
+++ b/EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootDxeStrings.uni
@@ -0,0 +1,41 @@
+/** @file
+ HII-to-Redfish memory driver.
+
+ (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/=#
+#langdef en-US "English"
+
+#string STR_FORM_SET_TITLE #language en-US "HII to Redfish
(Boot)"
+#string STR_FORM_SET_TITLE_HELP #language en-US "HII to
Redfish (Boot)"
+#string STR_FORM_TITLE #language en-US "HII to Redfish
Boot properties"
+
+#string STR_BOOT_ORDER #language en-US "Boot Order"
+#string STR_BOOT_ORDER_LIST #language en-US "Boot Order
List"
+#string STR_BOOT_ORDER_LIST_HELP #language en-US "Boot
Order List"
+
+#string STR_BOOT_SOURCE_OVERRIDE_ENABLED #language en-US
"Boot Source Override Enabled"
+#string STR_BOOT_SOURCE_OVERRIDE_ENABLED_HELP #language en-US
"Describes the state of the Boot Source Override feature."
+
+#string STR_BOOT_SOURCE_OVERRIDE_MODE #language en-US
"Boot Source Override Mode"
+#string STR_BOOT_SOURCE_OVERRIDE_MODE_HELP #language en-US
"The BIOS Boot Mode (either Legacy or UEFI) to be used when
BootSourceOverrideTarget boot source is booted from."
+
+#string STR_BOOT_SOURCE_OVERRIDE_TARGET #language en-US
"Boot Source Override Target"
+#string STR_BOOT_SOURCE_OVERRIDE_TARGET_HELP #language en-US
"The current boot source to be used at next boot instead of the normal boot
device, if BootSourceOverrideEnabled is true."
+
+#string STR_DISABLED #language en-US "Disabled"
+#string STR_ONCE #language en-US "Once"
+#string STR_CONTINUOUS #language en-US "Continuous"
+#string STR_UEFI #language en-US "UEFI"
+#string STR_LEGACY #language en-US "Legacy"
+#string STR_TARGET_NONE #language en-US "None"
+#string STR_TARGET_PXE #language en-US "Pxe"
+#string STR_TARGET_USB #language en-US "Usb"
+#string STR_TARGET_HDD #language en-US "Hdd"
+#string STR_TARGET_BIOS_SETUP #language en-US "Bios Setup
Menu"
+#string STR_TARGET_UEFI #language en-US "Uefi Target"
+#string STR_TARGET_UEFI_HTTP #language en-US "Uefi Http"
diff --git a/EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootVfr.vfr
b/EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootVfr.vfr
new file mode 100644
index 0000000000..3758de6bfd
--- /dev/null
+++ b/EmulatorPkg/Hii2RedfishBootDxe/Hii2RedfishBootVfr.vfr
@@ -0,0 +1,83 @@
+/** @file
+ HII-to-Redfish boot driver VFR file.
+
+ (C) Copyright 2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include "Hii2RedfishBootData.h"
+
+formset
+ guid = HII_2_REDFISH_BOOT_FORMSET_GUID,
+ title = STRING_TOKEN(STR_FORM_SET_TITLE),
+ help = STRING_TOKEN(STR_FORM_SET_TITLE_HELP),
+ classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID,
+
+ //
+ // Define a EFI variable Storage (EFI_IFR_VARSTORE_EFI) //
+ efivarstore HII_2_REDFISH_BOOT_EFI_VARSTORE_DATA,
+ attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS |
EFI_VARIABLE_NON_VOLATILE, // EFI variable attribures
+ name = Hii2RedfishBootEfiVar,
+ guid = HII_2_REDFISH_BOOT_FORMSET_GUID;
+
+ //
+ // Define a variable Storage for boot order // varstore
+ HII_2_REDFISH_BOOT_OPTION_VARSTORE_DATA,
+ varid = BOOT_OPTION_VAR_STORE_ID,
+ name = Hii2RedfishBootOptionVar,
+ guid = HII_2_REDFISH_BOOT_FORMSET_GUID;
+
+ //
+ // Define a Form (EFI_IFR_FORM)
+ //
+ form formid = FORM_ID, // Form ID
+ title = STRING_TOKEN(STR_FORM_TITLE); // Form title
+
+ oneof varid = Hii2RedfishBootEfiVar.BootSourceOverrideEnabled,
+ questionid = QUESTION_ID_BOOT_SOURCE_OVERRIDE_ENABLED,
+ prompt = STRING_TOKEN(STR_BOOT_SOURCE_OVERRIDE_ENABLED),
+ help =
STRING_TOKEN(STR_BOOT_SOURCE_OVERRIDE_ENABLED_HELP),
+ flags = INTERACTIVE | NUMERIC_SIZE_1,
+ option text = STRING_TOKEN(STR_DISABLED), value =
STR_DISABLED, flags = DEFAULT;
+ option text = STRING_TOKEN(STR_ONCE), value = STR_ONCE,
flags = 0;
+ option text = STRING_TOKEN(STR_CONTINUOUS), value =
STR_CONTINUOUS, flags = 0;
+ endoneof;
+
+ oneof varid = Hii2RedfishBootEfiVar.BootSourceOverrideMode,
+ questionid = QUESTION_ID_BOOT_SOURCE_OVERRIDE_MODE,
+ prompt = STRING_TOKEN(STR_BOOT_SOURCE_OVERRIDE_MODE),
+ help = STRING_TOKEN(STR_BOOT_SOURCE_OVERRIDE_MODE_HELP),
+ flags = INTERACTIVE | NUMERIC_SIZE_1,
+ option text = STRING_TOKEN(STR_UEFI), value = STR_UEFI,
flags = DEFAULT;
+ option text = STRING_TOKEN(STR_LEGACY), value = STR_LEGACY,
flags = 0;
+ endoneof;
+
+ oneof varid = Hii2RedfishBootEfiVar.BootSourceOverrideTarget,
+ questionid = QUESTION_ID_BOOT_SOURCE_OVERRIDE_TARGET,
+ prompt = STRING_TOKEN(STR_BOOT_SOURCE_OVERRIDE_TARGET),
+ help =
STRING_TOKEN(STR_BOOT_SOURCE_OVERRIDE_TARGET_HELP),
+ flags = INTERACTIVE | NUMERIC_SIZE_1,
+ option text = STRING_TOKEN(STR_TARGET_NONE), value =
STR_TARGET_NONE, flags = DEFAULT;
+ option text = STRING_TOKEN(STR_TARGET_PXE), value =
STR_TARGET_PXE, flags = 0;
+ option text = STRING_TOKEN(STR_TARGET_USB), value =
STR_TARGET_USB, flags = 0;
+ option text = STRING_TOKEN(STR_TARGET_HDD), value =
STR_TARGET_HDD, flags = 0;
+ option text = STRING_TOKEN(STR_TARGET_BIOS_SETUP), value =
STR_TARGET_BIOS_SETUP, flags = 0;
+ option text = STRING_TOKEN(STR_TARGET_UEFI), value =
STR_TARGET_UEFI, flags = 0;
+ option text = STRING_TOKEN(STR_TARGET_UEFI_HTTP), value =
STR_TARGET_UEFI_HTTP, flags = 0;
+ endoneof;
+
+ subtitle text = STRING_TOKEN(STR_BOOT_ORDER);
+
+ //
+ // This is where we will dynamically add choices for the Boot Manager
+ //
+ label LABEL_BOOT_OPTION;
+ label LABEL_BOOT_OPTION_END;
+
+ endform;
+endformset;
--
2.32.0.windows.2


Re: [PATCH 2/2] Platform/Sgi: Add serial debug controller to SSDT

Thanu Rangarajan <Thanu.Rangarajan@...>
 

Hi Rohit,

The decision to use the SBSA defined HID for the Generic UART was taken after extensive discussions within the Arm ecosystem. And as Sami points out, now that formal Linux driver support for this HID is available, it would be good if it is used by other components in the stack as well.

 

+ Samer for any additional comments/clarifications.

 

Regards,

Thanu

From: Sami Mujawar <Sami.Mujawar@...>
Date: Monday, 25 July 2022 at 16:12
To: Rohit Mathew <Rohit.Mathew@...>, "devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: Thanu Rangarajan <Thanu.Rangarajan@...>, nd <nd@...>
Subject: Re: [edk2-devel] [PATCH 2/2] Platform/Sgi: Add serial debug controller to SSDT

 

Hi Rohit,

Please find my response inline marked [SAMI].

Regards,

Sami Mujawar

On 22/07/2022 01:46 pm, Rohit Mathew wrote:

Hi Sami,

Thank you for the review.
Regarding the use of Dynamic Tables Framework, there are no short term plans to migrate to it. Please find my response for your comment inline - 

On Thu, Jul 21, 2022 at 01:42 PM, Sami Mujawar wrote:

Hi Rohit,

Have you considered moving to use Dynamic Tables Framework? There is
just too much repetition in this series which can be easily avoided. It
will also make the code more maintainable.

Apart from this I have a comment marked inline as [SAMI].

Regards,

Sami Mujawar

On 04/07/2022 05:59 pm, Rohit Mathew wrote:

Add a new device entry in the SSDT ACPI table to describe the serial
port used as the debug port. On the Neoverse reference design platforms,
the UART0 port of the SoC is used as the debug port.

Signed-off-by: Rohit Mathew <rohit.mathew@...>
---
Platform/ARM/SgiPkg/AcpiTables/RdE1EdgeAcpiTables.inf | 1 +
Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeAcpiTables.inf | 1 +
Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeX2AcpiTables.inf | 1 +
Platform/ARM/SgiPkg/AcpiTables/RdN2AcpiTables.inf | 1 +
Platform/ARM/SgiPkg/AcpiTables/RdN2Cfg1AcpiTables.inf | 1 +
Platform/ARM/SgiPkg/AcpiTables/RdV1AcpiTables.inf | 1 +
Platform/ARM/SgiPkg/AcpiTables/RdV1McAcpiTables.inf | 1 +
Platform/ARM/SgiPkg/AcpiTables/Sgi575AcpiTables.inf | 1 +
Platform/ARM/SgiPkg/AcpiTables/SsdtRos.asl | 15 +++++++++++++++
9 files changed, 23 insertions(+)

diff --git a/Platform/ARM/SgiPkg/AcpiTables/RdE1EdgeAcpiTables.inf b/Platform/ARM/SgiPkg/AcpiTables/RdE1EdgeAcpiTables.inf
index d2935f1e73e1..d46ae0274d90 100644
--- a/Platform/ARM/SgiPkg/AcpiTables/RdE1EdgeAcpiTables.inf
+++ b/Platform/ARM/SgiPkg/AcpiTables/RdE1EdgeAcpiTables.inf
@@ -39,6 +39,7 @@ [Packages]
[FixedPcd]
gArmPlatformTokenSpaceGuid.PcdCoreCount
gArmPlatformTokenSpaceGuid.PcdClusterCount
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgInterrupt
gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
gArmPlatformTokenSpaceGuid.PL011UartInterrupt

diff --git a/Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeAcpiTables.inf b/Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeAcpiTables.inf
index 73f47ece7718..4bf681d3bc2e 100644
--- a/Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeAcpiTables.inf
+++ b/Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeAcpiTables.inf
@@ -39,6 +39,7 @@ [Packages]
[FixedPcd]
gArmPlatformTokenSpaceGuid.PcdCoreCount
gArmPlatformTokenSpaceGuid.PcdClusterCount
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgInterrupt
gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
gArmPlatformTokenSpaceGuid.PL011UartInterrupt

diff --git a/Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeX2AcpiTables.inf b/Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeX2AcpiTables.inf
index da14120bde69..89f532217ceb 100644
--- a/Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeX2AcpiTables.inf
+++ b/Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeX2AcpiTables.inf
@@ -41,6 +41,7 @@ [Packages]
[FixedPcd]
gArmPlatformTokenSpaceGuid.PcdCoreCount
gArmPlatformTokenSpaceGuid.PcdClusterCount
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgInterrupt
gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
gArmPlatformTokenSpaceGuid.PL011UartInterrupt

diff --git a/Platform/ARM/SgiPkg/AcpiTables/RdN2AcpiTables.inf b/Platform/ARM/SgiPkg/AcpiTables/RdN2AcpiTables.inf
index 90976250445e..66d5422df36b 100644
--- a/Platform/ARM/SgiPkg/AcpiTables/RdN2AcpiTables.inf
+++ b/Platform/ARM/SgiPkg/AcpiTables/RdN2AcpiTables.inf
@@ -37,6 +37,7 @@ [Packages]
Platform/ARM/SgiPkg/SgiPlatform.dec

[FixedPcd]
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgInterrupt
gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
gArmPlatformTokenSpaceGuid.PL011UartInterrupt
gArmPlatformTokenSpaceGuid.PcdCoreCount
diff --git a/Platform/ARM/SgiPkg/AcpiTables/RdN2Cfg1AcpiTables.inf b/Platform/ARM/SgiPkg/AcpiTables/RdN2Cfg1AcpiTables.inf
index 95fb446c105d..742734ab7348 100644
--- a/Platform/ARM/SgiPkg/AcpiTables/RdN2Cfg1AcpiTables.inf
+++ b/Platform/ARM/SgiPkg/AcpiTables/RdN2Cfg1AcpiTables.inf
@@ -37,6 +37,7 @@ [Packages]
Platform/ARM/SgiPkg/SgiPlatform.dec

[FixedPcd]
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgInterrupt
gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
gArmPlatformTokenSpaceGuid.PcdCoreCount
gArmPlatformTokenSpaceGuid.PcdClusterCount
diff --git a/Platform/ARM/SgiPkg/AcpiTables/RdV1AcpiTables.inf b/Platform/ARM/SgiPkg/AcpiTables/RdV1AcpiTables.inf
index 3540575dd641..cc41dda1a135 100644
--- a/Platform/ARM/SgiPkg/AcpiTables/RdV1AcpiTables.inf
+++ b/Platform/ARM/SgiPkg/AcpiTables/RdV1AcpiTables.inf
@@ -37,6 +37,7 @@ [Packages]
Platform/ARM/SgiPkg/SgiPlatform.dec

[FixedPcd]
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgInterrupt
gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
gArmPlatformTokenSpaceGuid.PL011UartInterrupt
gArmPlatformTokenSpaceGuid.PcdCoreCount
diff --git a/Platform/ARM/SgiPkg/AcpiTables/RdV1McAcpiTables.inf b/Platform/ARM/SgiPkg/AcpiTables/RdV1McAcpiTables.inf
index c6bd69b4a538..ecb42bf3cc33 100644
--- a/Platform/ARM/SgiPkg/AcpiTables/RdV1McAcpiTables.inf
+++ b/Platform/ARM/SgiPkg/AcpiTables/RdV1McAcpiTables.inf
@@ -39,6 +39,7 @@ [Packages]
Platform/ARM/SgiPkg/SgiPlatform.dec

[FixedPcd]
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgInterrupt
gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
gArmPlatformTokenSpaceGuid.PL011UartInterrupt
gArmPlatformTokenSpaceGuid.PcdCoreCount
diff --git a/Platform/ARM/SgiPkg/AcpiTables/Sgi575AcpiTables.inf b/Platform/ARM/SgiPkg/AcpiTables/Sgi575AcpiTables.inf
index cb3f3fcdb9b6..379b5c9e6122 100644
--- a/Platform/ARM/SgiPkg/AcpiTables/Sgi575AcpiTables.inf
+++ b/Platform/ARM/SgiPkg/AcpiTables/Sgi575AcpiTables.inf
@@ -39,6 +39,7 @@ [Packages]
[FixedPcd]
gArmPlatformTokenSpaceGuid.PcdCoreCount
gArmPlatformTokenSpaceGuid.PcdClusterCount
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgInterrupt
gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
gArmPlatformTokenSpaceGuid.PL011UartInterrupt

diff --git a/Platform/ARM/SgiPkg/AcpiTables/SsdtRos.asl b/Platform/ARM/SgiPkg/AcpiTables/SsdtRos.asl
index fd20c67e1225..ab8578072836 100644
--- a/Platform/ARM/SgiPkg/AcpiTables/SsdtRos.asl
+++ b/Platform/ARM/SgiPkg/AcpiTables/SsdtRos.asl
@@ -29,6 +29,21 @@ DefinitionBlock ("SsdtRosTable.aml", "SSDT", 2, "ARMLTD", "ARMSGI",
})
}

+ Device (COM1) {
+ Name (_HID, "ARMH0011")
+ Name (_CID, "ARMH0011")

[SAMI] Any reason for not using  ARMHB000 (see Section 2.3 of the ACPI
for Arm Components 1.1 specification)?

[Rohit]: COM1 is based on PL011. Since PL011 would satisfy SBSA compliance, we have used PL011's HID.

[SAMI] Following is an extract from Section 2.3 of the 'ACPI for Arm Components 1.1' specification.

"Some operating systems use the PL011 HID (see Table 5 above)
to bind to the Arm Generic UART in the system. While this
practice is flawed and not encouraged by Arm, Arm
acknowledges that it must be permitted until formal support for
the Arm Generic UART HID is made available in these operating
systems.
Arm strongly recommends use of the Arm Generic UART HID
going forward."

1. The Arm Generic UART is a subset of PL011. This means using the ARMHB000 should not be an issue.

2. This file is common to all platforms in SgiPkg, which are infrastructure platforms.

3. Some opreating systems (like Linux) have already integrated support for ARMHB000.

    Ref: serial: pl011: Add ACPI SBSA UART match id

Considering the above, I think ARMHB000 should be used, here.

[/SAMI]

 

+ Name (_UID, One)
+ Name (_STA, 0xF)
+ Name (_CRS, ResourceTemplate () {
+ Memory32Fixed (
+ ReadWrite,
+ FixedPcdGet64 (PcdSerialDbgRegisterBase),
+ 0x1000
+ )
+ Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { FixedPcdGet32 (PcdSerialDbgInterrupt) }
+ })
+ }
+
// VIRTIO DISK
Device (VR00) {
Name (_HID, "LNRO0005")

Regards,
Rohit

IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.


Re: [PATCH 1/1] MdeModulePkg: Enhance bus scan for all root bridge instances

Nong, Foster <foster.nong@...>
 

Hi Mike,

Yes. With this chance, each root bridge will have the bus resource size except the one which
Meet the bus shortage case. Then the Bus Rebalance handle of EfiPciHostBridgeEndBusAllocation on
platform BIOS will Have a chance to adjust the bus resource assignment for each root bridges
which meet the Bus shortage case.

Best Regards
Foster Nong
EXT: 021-61164849

-----Original Message-----
From: Kinney, Michael D <michael.d.kinney@...>
Sent: Saturday, July 23, 2022 7:49 AM
To: devel@edk2.groups.io; Nong, Foster <foster.nong@...>; Ni, Ray <ray.ni@...>; Kinney, Michael D <michael.d.kinney@...>
Subject: RE: [edk2-devel] [PATCH 1/1] MdeModulePkg: Enhance bus scan for all root bridge instances

Hi Foster,

Does this change provide the resource size requirements for each root bridge so a rebalance or larger resource allocation can be performed?

Thanks,

Mike

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Foster
Nong
Sent: Friday, July 22, 2022 2:10 AM
To: devel@edk2.groups.io
Cc: Nong, Foster <foster.nong@...>
Subject: [edk2-devel] [PATCH 1/1] MdeModulePkg: Enhance bus scan for
all root bridge instances

Ref:https://bugzilla.tianocore.org/show_bug.cgi?id=4000

Change flow to bus scan all root bridge instances even when any one
root bridge meet bus resource OUT_OF_RESOURCE case.
thus platform handler of "EfiPciHostBridgeEndBusAllocation" has an
chance to do relative pci bus rebalance to handle this case.

Signed-off-by: Foster Nong <foster.nong@...>
---
MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c
b/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c
index 63d149b3b8c0..a89f912de85b 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c
@@ -1528,6 +1528,7 @@ PciHostBridgeEnumerator (
UINT8 StartBusNumber;
LIST_ENTRY RootBridgeList;
LIST_ENTRY *Link;
+ EFI_STATUS RootBridgeEnumerationStatus;

if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {
InitializeHotPlugSupport ();
@@ -1546,6 +1547,7 @@ PciHostBridgeEnumerator (

DEBUG ((DEBUG_INFO, "PCI Bus First Scanning\n"));
RootBridgeHandle = NULL;
+ RootBridgeEnumerationStatus = EFI_SUCCESS;
while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) {
//
// if a root bridge instance is found, create root bridge device
for it @@ -1572,7 +1574,7 @@ PciHostBridgeEnumerator (
}

if (EFI_ERROR (Status)) {
- return Status;
+ RootBridgeEnumerationStatus = Status;
}
}

@@ -1581,6 +1583,10 @@ PciHostBridgeEnumerator (
//
NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation);

+ if (EFI_ERROR (RootBridgeEnumerationStatus)) {
+ return RootBridgeEnumerationStatus; }
+
if ((gPciHotPlugInit != NULL) && FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) {
//
// Reset all assigned PCI bus number in all PPB @@ -1659,7
+1665,7 @@ PciHostBridgeEnumerator (

DestroyRootBridge (RootBridgeDev);
if (EFI_ERROR (Status)) {
- return Status;
+ RootBridgeEnumerationStatus = Status;
}
}

@@ -1667,6 +1673,10 @@ PciHostBridgeEnumerator (
// Notify the bus allocation phase is to end for the 2nd time
//
NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation);
+
+ if (EFI_ERROR (RootBridgeEnumerationStatus)) {
+ return RootBridgeEnumerationStatus;
+ }
}

//
--
2.26.2.windows.1





Re: [PATCH 1/1] ArmPlatformPkg/PrePeiCore: Print the firmware version early in boot

Sami Mujawar
 

Hi Rebecca,

Please find my response inline marked [SAMI].

Regards,

Sami Mujawar

On 21/07/2022 05:23 pm, Sami Mujawar via groups.io wrote:
Hi Rebecca, Ard,

On Tue, May 3, 2022 at 12:43 AM, Ard Biesheuvel wrote:
// Data Cache enabled on Primary core when MMU is enabled.
ArmDisableDataCache ();
// Invalidate instruction cache
@@ -90,6 +95,18 @@ CEntryPoint (

// If not primary Jump to Secondary Main
if (ArmPlatformIsPrimaryCore (MpId)) {
+ // Initialize the Serial Port
+ SerialPortInitialize ();
+ CharCount = AsciiSPrint (
+ Buffer,
+ sizeof (Buffer),
+ "UEFI firmware (version %s built at %a on %a)\n\r",
+ (CHAR16 *)PcdGetPtr (PcdFirmwareVersionString),
Given that this runs before any library constructors are called, I'd
be inclined to use FixedPcdGetPtr() here (and [FixedPcd] in the .INFs
below), to ensure that we don't dereference garbage.

I also wonder whether we need a call to
ProcessLibraryConstructorList() somewhere.
[SAMI] There is a patch at https://edk2.groups.io/g/devel/message/91113 which aims to call ProcessLibraryConstructorList(). The idea being that the DebugLib constructor would be called which initializes the serial port.
So, maybe these patches need adjustment so that we avoid calling SerialPortInitialize () twice.
[/SAMI]

[/SAMI] I had a look at the SerialPortInitialize() implementation for PL011 and 16550 UARTs and it appears that both check the current settings before programming the UART. Therefore, please ignore my comment above.

[/SAMI]

regards,

Sami Mujawar

+ __TIME__,
+ __DATE__
+ );
+ SerialPortWrite ((UINT8 *)Buffer, CharCount);
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.


Re: [edk2][PATCH V4 1/1] ArmPlatformPkg/PrePeiCore: Invoke constructors for SEC phase

Sami Mujawar
 

Hi Rohit,

This patch looks good to me.

Reviewed-by: Sami Mujawar <sami.mujawar@...>

Regards,

Sami Mujawar

On 22/07/2022 06:02 pm, Rohit Mathew wrote:
On platforms that do not have the serial console port pre-initialized
prior to the SEC phase and due to the absence of a call to
"SerialPortInitialize", this results in missing debug logs. So, call
the auto-generated "ProcessLibraryConstructorList" function from SEC
phase to have all the dependent library constructors called
(this includes a call to "SerialPortInitialize").

Signed-off-by: Rohit Mathew <rohit.mathew@...>
---
ArmPlatformPkg/PrePeiCore/PrePeiCore.h | 12 +++++++++++-
ArmPlatformPkg/PrePeiCore/PrePeiCore.c | 6 +++++-
2 files changed, 16 insertions(+), 2 deletions(-)

Changes since V1:
- Rebased on top of latest master branch.
- Addressed comments from Ard.

Changes since V2:
- Rebased on top of latest master branch.

Changes since V3:
- Addressed comments from Sami.

Link to github branch for the patch -
https://github.com/rohit-arm/edk2/tree/sec_constructor_issue

diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCore.h b/ArmPlatformPkg/PrePeiCore/PrePeiCore.h
index 0345dd7bdd2a..c1e13e23e11e 100644
--- a/ArmPlatformPkg/PrePeiCore/PrePeiCore.h
+++ b/ArmPlatformPkg/PrePeiCore/PrePeiCore.h
@@ -1,7 +1,7 @@
/** @file
Main file supporting the transition to PEI Core in Normal World for Versatile Express
- Copyright (c) 2011, ARM Limited. All rights reserved.
+ Copyright (c) 2011 - 2022, ARM Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -73,4 +73,14 @@ PeiCommonExceptionEntry (
IN UINTN LR
);
+/*
+ * Autogenerated function that calls the library constructors for all of the
+ * module's dependent libraries.
+ */
+VOID
+EFIAPI
+ProcessLibraryConstructorList (
+ VOID
+ );
+
#endif
diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCore.c b/ArmPlatformPkg/PrePeiCore/PrePeiCore.c
index 6dd9bcdea24f..9c4b25df953d 100644
--- a/ArmPlatformPkg/PrePeiCore/PrePeiCore.c
+++ b/ArmPlatformPkg/PrePeiCore/PrePeiCore.c
@@ -1,7 +1,7 @@
/** @file
Main file supporting the transition to PEI Core in Normal World for Versatile Express
- Copyright (c) 2011-2014, ARM Limited. All rights reserved.
+ Copyright (c) 2011 - 2022, ARM Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -90,6 +90,10 @@ CEntryPoint (
// If not primary Jump to Secondary Main
if (ArmPlatformIsPrimaryCore (MpId)) {
+ // Invoke "ProcessLibraryConstructorList" to have all library constructors
+ // called.
+ ProcessLibraryConstructorList ();
+
// Initialize the Debug Agent for Source Level Debugging
InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL);
SaveAndSetDebugTimerInterrupt (TRUE);


Re: [PATCH 2/2] Platform/Sgi: Add serial debug controller to SSDT

Sami Mujawar
 

Hi Rohit,

Please find my response inline marked [SAMI].

Regards,

Sami Mujawar

On 22/07/2022 01:46 pm, Rohit Mathew wrote:
Hi Sami,

Thank you for the review.
Regarding the use of Dynamic Tables Framework, there are no short term plans to migrate to it. Please find my response for your comment inline - 

On Thu, Jul 21, 2022 at 01:42 PM, Sami Mujawar wrote:
Hi Rohit,

Have you considered moving to use Dynamic Tables Framework? There is
just too much repetition in this series which can be easily avoided. It
will also make the code more maintainable.

Apart from this I have a comment marked inline as [SAMI].

Regards,

Sami Mujawar

On 04/07/2022 05:59 pm, Rohit Mathew wrote:
Add a new device entry in the SSDT ACPI table to describe the serial
port used as the debug port. On the Neoverse reference design platforms,
the UART0 port of the SoC is used as the debug port.

Signed-off-by: Rohit Mathew <rohit.mathew@...>
---
Platform/ARM/SgiPkg/AcpiTables/RdE1EdgeAcpiTables.inf | 1 +
Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeAcpiTables.inf | 1 +
Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeX2AcpiTables.inf | 1 +
Platform/ARM/SgiPkg/AcpiTables/RdN2AcpiTables.inf | 1 +
Platform/ARM/SgiPkg/AcpiTables/RdN2Cfg1AcpiTables.inf | 1 +
Platform/ARM/SgiPkg/AcpiTables/RdV1AcpiTables.inf | 1 +
Platform/ARM/SgiPkg/AcpiTables/RdV1McAcpiTables.inf | 1 +
Platform/ARM/SgiPkg/AcpiTables/Sgi575AcpiTables.inf | 1 +
Platform/ARM/SgiPkg/AcpiTables/SsdtRos.asl | 15 +++++++++++++++
9 files changed, 23 insertions(+)

diff --git a/Platform/ARM/SgiPkg/AcpiTables/RdE1EdgeAcpiTables.inf b/Platform/ARM/SgiPkg/AcpiTables/RdE1EdgeAcpiTables.inf
index d2935f1e73e1..d46ae0274d90 100644
--- a/Platform/ARM/SgiPkg/AcpiTables/RdE1EdgeAcpiTables.inf
+++ b/Platform/ARM/SgiPkg/AcpiTables/RdE1EdgeAcpiTables.inf
@@ -39,6 +39,7 @@ [Packages]
[FixedPcd]
gArmPlatformTokenSpaceGuid.PcdCoreCount
gArmPlatformTokenSpaceGuid.PcdClusterCount
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgInterrupt
gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
gArmPlatformTokenSpaceGuid.PL011UartInterrupt

diff --git a/Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeAcpiTables.inf b/Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeAcpiTables.inf
index 73f47ece7718..4bf681d3bc2e 100644
--- a/Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeAcpiTables.inf
+++ b/Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeAcpiTables.inf
@@ -39,6 +39,7 @@ [Packages]
[FixedPcd]
gArmPlatformTokenSpaceGuid.PcdCoreCount
gArmPlatformTokenSpaceGuid.PcdClusterCount
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgInterrupt
gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
gArmPlatformTokenSpaceGuid.PL011UartInterrupt

diff --git a/Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeX2AcpiTables.inf b/Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeX2AcpiTables.inf
index da14120bde69..89f532217ceb 100644
--- a/Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeX2AcpiTables.inf
+++ b/Platform/ARM/SgiPkg/AcpiTables/RdN1EdgeX2AcpiTables.inf
@@ -41,6 +41,7 @@ [Packages]
[FixedPcd]
gArmPlatformTokenSpaceGuid.PcdCoreCount
gArmPlatformTokenSpaceGuid.PcdClusterCount
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgInterrupt
gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
gArmPlatformTokenSpaceGuid.PL011UartInterrupt

diff --git a/Platform/ARM/SgiPkg/AcpiTables/RdN2AcpiTables.inf b/Platform/ARM/SgiPkg/AcpiTables/RdN2AcpiTables.inf
index 90976250445e..66d5422df36b 100644
--- a/Platform/ARM/SgiPkg/AcpiTables/RdN2AcpiTables.inf
+++ b/Platform/ARM/SgiPkg/AcpiTables/RdN2AcpiTables.inf
@@ -37,6 +37,7 @@ [Packages]
Platform/ARM/SgiPkg/SgiPlatform.dec

[FixedPcd]
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgInterrupt
gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
gArmPlatformTokenSpaceGuid.PL011UartInterrupt
gArmPlatformTokenSpaceGuid.PcdCoreCount
diff --git a/Platform/ARM/SgiPkg/AcpiTables/RdN2Cfg1AcpiTables.inf b/Platform/ARM/SgiPkg/AcpiTables/RdN2Cfg1AcpiTables.inf
index 95fb446c105d..742734ab7348 100644
--- a/Platform/ARM/SgiPkg/AcpiTables/RdN2Cfg1AcpiTables.inf
+++ b/Platform/ARM/SgiPkg/AcpiTables/RdN2Cfg1AcpiTables.inf
@@ -37,6 +37,7 @@ [Packages]
Platform/ARM/SgiPkg/SgiPlatform.dec

[FixedPcd]
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgInterrupt
gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
gArmPlatformTokenSpaceGuid.PcdCoreCount
gArmPlatformTokenSpaceGuid.PcdClusterCount
diff --git a/Platform/ARM/SgiPkg/AcpiTables/RdV1AcpiTables.inf b/Platform/ARM/SgiPkg/AcpiTables/RdV1AcpiTables.inf
index 3540575dd641..cc41dda1a135 100644
--- a/Platform/ARM/SgiPkg/AcpiTables/RdV1AcpiTables.inf
+++ b/Platform/ARM/SgiPkg/AcpiTables/RdV1AcpiTables.inf
@@ -37,6 +37,7 @@ [Packages]
Platform/ARM/SgiPkg/SgiPlatform.dec

[FixedPcd]
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgInterrupt
gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
gArmPlatformTokenSpaceGuid.PL011UartInterrupt
gArmPlatformTokenSpaceGuid.PcdCoreCount
diff --git a/Platform/ARM/SgiPkg/AcpiTables/RdV1McAcpiTables.inf b/Platform/ARM/SgiPkg/AcpiTables/RdV1McAcpiTables.inf
index c6bd69b4a538..ecb42bf3cc33 100644
--- a/Platform/ARM/SgiPkg/AcpiTables/RdV1McAcpiTables.inf
+++ b/Platform/ARM/SgiPkg/AcpiTables/RdV1McAcpiTables.inf
@@ -39,6 +39,7 @@ [Packages]
Platform/ARM/SgiPkg/SgiPlatform.dec

[FixedPcd]
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgInterrupt
gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
gArmPlatformTokenSpaceGuid.PL011UartInterrupt
gArmPlatformTokenSpaceGuid.PcdCoreCount
diff --git a/Platform/ARM/SgiPkg/AcpiTables/Sgi575AcpiTables.inf b/Platform/ARM/SgiPkg/AcpiTables/Sgi575AcpiTables.inf
index cb3f3fcdb9b6..379b5c9e6122 100644
--- a/Platform/ARM/SgiPkg/AcpiTables/Sgi575AcpiTables.inf
+++ b/Platform/ARM/SgiPkg/AcpiTables/Sgi575AcpiTables.inf
@@ -39,6 +39,7 @@ [Packages]
[FixedPcd]
gArmPlatformTokenSpaceGuid.PcdCoreCount
gArmPlatformTokenSpaceGuid.PcdClusterCount
+ gArmPlatformTokenSpaceGuid.PcdSerialDbgInterrupt
gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase
gArmPlatformTokenSpaceGuid.PL011UartInterrupt

diff --git a/Platform/ARM/SgiPkg/AcpiTables/SsdtRos.asl b/Platform/ARM/SgiPkg/AcpiTables/SsdtRos.asl
index fd20c67e1225..ab8578072836 100644
--- a/Platform/ARM/SgiPkg/AcpiTables/SsdtRos.asl
+++ b/Platform/ARM/SgiPkg/AcpiTables/SsdtRos.asl
@@ -29,6 +29,21 @@ DefinitionBlock ("SsdtRosTable.aml", "SSDT", 2, "ARMLTD", "ARMSGI",
})
}

+ Device (COM1) {
+ Name (_HID, "ARMH0011")
+ Name (_CID, "ARMH0011")
[SAMI] Any reason for not using  ARMHB000 (see Section 2.3 of the ACPI
for Arm Components 1.1 specification)?
[Rohit]: COM1 is based on PL011. Since PL011 would satisfy SBSA compliance, we have used PL011's HID.

[SAMI] Following is an extract from Section 2.3 of the 'ACPI for Arm Components 1.1' specification.

"Some operating systems use the PL011 HID (see Table 5 above)
to bind to the Arm Generic UART in the system. While this
practice is flawed and not encouraged by Arm, Arm
acknowledges that it must be permitted until formal support for
the Arm Generic UART HID is made available in these operating
systems.
Arm strongly recommends use of the Arm Generic UART HID
going forward."

1. The Arm Generic UART is a subset of PL011. This means using the ARMHB000 should not be an issue.

2. This file is common to all platforms in SgiPkg, which are infrastructure platforms.

3. Some opreating systems (like Linux) have already integrated support for ARMHB000.

    Ref: serial: pl011: Add ACPI SBSA UART match id

Considering the above, I think ARMHB000 should be used, here.

[/SAMI]


+ Name (_UID, One)
+ Name (_STA, 0xF)
+ Name (_CRS, ResourceTemplate () {
+ Memory32Fixed (
+ ReadWrite,
+ FixedPcdGet64 (PcdSerialDbgRegisterBase),
+ 0x1000
+ )
+ Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { FixedPcdGet32 (PcdSerialDbgInterrupt) }
+ })
+ }
+
// VIRTIO DISK
Device (VR00) {
Name (_HID, "LNRO0005")
Regards,
Rohit


回复: [PATCH v4 00/21] Add Raw algorithm support using Arm FW-TRNG interface

gaoliming
 

Pierre:
The change in MdePkg is good to me. Reviewed-by: Liming Gao
<gaoliming@...>

Thanks
Liming

-----邮件原件-----
发件人: Pierre.Gondois@... <Pierre.Gondois@...>
发送时间: 2022年7月22日 22:32
收件人: devel@edk2.groups.io
抄送: Sami Mujawar <sami.mujawar@...>; Leif Lindholm
<quic_llindhol@...>; Ard Biesheuvel <ardb+tianocore@...>;
Rebecca Cran <rebecca@...>; Michael D Kinney
<michael.d.kinney@...>; Liming Gao <gaoliming@...>;
Jiewen Yao <jiewen.yao@...>; Jian J Wang <jian.j.wang@...>;
Pierre Gondois <pierre.gondois@...>
主题: [PATCH v4 00/21] Add Raw algorithm support using Arm FW-TRNG
interface

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

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

The Arm True Random Number Generator Firmware, Interface 1.0,
specification
defines an interface between an Operating System (OS) executing at EL1 and
Firmware (FW) exposing a conditioned entropy source that is provided by a
TRNG back end.
This patch-set:
- defines a TRNG library class that provides an interface to access the
entropy source on a platform.
- implements a TRNG library instance that uses the Arm FW-TRNG interface.
- Adds RawAlgorithm support to RngDxe for Arm architecture using the Arm
FW-TRNG interface.
- Enables RNG support using FW-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
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

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 (13):
ArmPkg/ArmMonitorLib: Definition for ArmMonitorLib library class
ArmPkg/ArmMonitorLib: Add ArmMonitorLib
ArmPkg/ArmHvcNullLib: Add NULL instance of ArmHvcLib
MdePkg/BaseRngLib: Rename ArmReadIdIsar0() to ArmGetFeatRng()
ArmPkg/ArmLib: Add ArmReadIdIsar0() helper
ArmPkg/ArmLib: Add ArmHasRngExt()
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/TrngLib: Definition for TRNG library class interface
MdePkg/TrngLib: Add NULL instance of TRNG Library
ArmPkg: Add FID definitions for Firmware TRNG
ArmPkg/TrngLib: Add Arm Firmware TRNG library
SecurityPkg/RngDxe: Rename RdRandGenerateEntropy to generic name
SecurityPkg/RngDxe: Add AArch64 RawAlgorithm support through TrngLib
ArmVirtPkg: Kvmtool: Add RNG support using FW-TRNG interface

ArmPkg/ArmPkg.dec | 12 +-
ArmPkg/ArmPkg.dsc | 3 +
ArmPkg/Include/IndustryStandard/ArmStdSmc.h | 109 ++++-
ArmPkg/Include/Library/ArmLib.h | 12 +-
ArmPkg/Include/Library/ArmMonitorLib.h | 42 ++
ArmPkg/Library/ArmFwTrngLib/ArmFwTrngDefs.h | 50 +++
ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.c | 403
++++++++++++++++++
ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.inf | 29 ++
ArmPkg/Library/ArmHvcNullLib/ArmHvcNullLib.c | 29 ++
.../Library/ArmHvcNullLib/ArmHvcNullLib.inf | 22 +
ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c | 15 +-
ArmPkg/Library/ArmLib/AArch64/AArch64Lib.h | 14 +-
.../Library/ArmLib/AArch64/AArch64Support.S | 7 +-
ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c | 16 +-
ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.c | 34 ++
.../Library/ArmMonitorLib/ArmMonitorLib.inf | 29 ++
ArmVirtPkg/ArmVirtKvmTool.dsc | 10 +
ArmVirtPkg/ArmVirtKvmTool.fdf | 5 +
MdePkg/Include/Library/TrngLib.h | 121 ++++++
.../{ArmReadIdIsar0.S => ArmGetFeatRng.S} | 8 +-
.../{ArmReadIdIsar0.asm => ArmGetFeatRng.asm} | 8 +-
MdePkg/Library/BaseRngLib/AArch64/ArmRng.h | 2 +-
MdePkg/Library/BaseRngLib/AArch64/Rndr.c | 2 +-
MdePkg/Library/BaseRngLib/BaseRngLib.inf | 4 +-
.../Library/BaseTrngLibNull/BaseTrngLibNull.c | 135 ++++++
.../BaseTrngLibNull/BaseTrngLibNull.inf | 30 ++
.../BaseTrngLibNull/BaseTrngLibNull.uni | 12 +
MdePkg/MdePkg.dec | 5 +
MdePkg/MdePkg.dsc | 1 +
.../RngDxe/AArch64/AArch64Algo.c | 72 ++++
.../RngDxe/Arm/ArmAlgo.c | 51 +++
.../RngDxe/{AArch64/RngDxe.c => 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 +-
40 files changed, 1575 insertions(+), 172 deletions(-)
create mode 100644 ArmPkg/Include/Library/ArmMonitorLib.h
create mode 100644 ArmPkg/Library/ArmFwTrngLib/ArmFwTrngDefs.h
create mode 100644 ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.c
create mode 100644 ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.inf
create mode 100644 ArmPkg/Library/ArmHvcNullLib/ArmHvcNullLib.c
create mode 100644 ArmPkg/Library/ArmHvcNullLib/ArmHvcNullLib.inf
create mode 100644 ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.c
create mode 100644 ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.inf
create mode 100644 MdePkg/Include/Library/TrngLib.h
rename MdePkg/Library/BaseRngLib/AArch64/{ArmReadIdIsar0.S =>
ArmGetFeatRng.S} (78%)
rename MdePkg/Library/BaseRngLib/AArch64/{ArmReadIdIsar0.asm =>
ArmGetFeatRng.asm} (81%)
create mode 100644 MdePkg/Library/BaseTrngLibNull/BaseTrngLibNull.c
create mode 100644 MdePkg/Library/BaseTrngLibNull/BaseTrngLibNull.inf
create mode 100644 MdePkg/Library/BaseTrngLibNull/BaseTrngLibNull.uni
create mode 100644
SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/AArch64Algo.c
create mode 100644
SecurityPkg/RandomNumberGenerator/RngDxe/Arm/ArmAlgo.c
rename SecurityPkg/RandomNumberGenerator/RngDxe/{AArch64/RngDxe.c
=> ArmRngDxe.c} (64%)
create mode 100644
SecurityPkg/RandomNumberGenerator/RngDxe/ArmTrng.c
delete mode 100644
SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.h

--
2.25.1


回复: 回复: [edk2-devel] [PATCHv3 1/1] MdePkg/UefiDevicePathLib: Add support for PEIMs

gaoliming
 

This change has been merged in edk2 master.

-----邮件原件-----
发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 gaoliming via
groups.io
发送时间: 2022年7月13日 15:48
收件人: devel@edk2.groups.io; Kun.Qin@...; 'Kinney, Michael D'
<michael.d.kinney@...>; 'Albecki, Mateusz'
<mateusz.albecki@...>
抄送: 'Liu, Zhiguang' <zhiguang.liu@...>
主题: 回复: 回复: [edk2-devel] [PATCHv3 1/1] MdePkg/UefiDevicePathLib:
Add support for PEIMs


That's great. I give my reviewed-by for this patch. Reviewed-by: Liming Gao
<gaoliming@...>

Thanks
Liming
-----邮件原件-----
发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Kun Qin via
groups.io
发送时间: 2022年7月12日 5:30
收件人: gaoliming <gaoliming@...>; devel@edk2.groups.io;
Kinney, Michael D <michael.d.kinney@...>; 'Albecki, Mateusz'
<mateusz.albecki@...>
抄送: 'Liu, Zhiguang' <zhiguang.liu@...>
主题: Re: 回复: [edk2-devel] [PATCHv3 1/1] MdePkg/UefiDevicePathLib:
Add
support for PEIMs

Liming/Mike,

I think making MM instance to be a base version makes sense, too. Thanks
for
the suggestion.

Regards,
Kun

-----Original Message-----
From: gaoliming <gaoliming@...>
Sent: Sunday, July 10, 2022 11:49 PM
To: devel@edk2.groups.io; Kinney, Michael D
<michael.d.kinney@...>;
'Albecki, Mateusz' <mateusz.albecki@...>
Cc: 'Liu, Zhiguang' <zhiguang.liu@...>; Kun Qin
<Kun.Qin@...>
Subject: [EXTERNAL] 回复: [edk2-devel] [PATCHv3 1/1]
MdePkg/UefiDevicePathLib: Add support for PEIMs

Mike:
Thanks for your suggestion. If there is no objection to change the file
name,
this patch will be better.

Thanks
Liming
-----邮件原件-----
发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Michael
D
Kinney
发送时间: 2022年7月8日 6:06
收件人: Gao, Liming <gaoliming@...>; Albecki, Mateusz
<mateusz.albecki@...>; devel@edk2.groups.io; Kinney, Michael D
<michael.d.kinney@...>
抄送: Liu, Zhiguang <zhiguang.liu@...>
主题: Re: [edk2-devel] [PATCHv3 1/1] MdePkg/UefiDevicePathLib: Add
support for PEIMs

Hi Liming,

I think the current Mm specific INF is actually compatible with all
module types.

Why not add a Base version that can be used by any module?

Using Peim in name implies it is only compatible with PEIMs which is not
true.

For the compatibility question, I would like to see feedback from Mm
maintainers to see if they would accept a library name change to a
more general purpose Base INF.

Mike

-----Original Message-----
From: gaoliming <gaoliming@...>
Sent: Wednesday, July 6, 2022 6:37 PM
To: Albecki, Mateusz <mateusz.albecki@...>;
devel@edk2.groups.io
Cc: Kinney, Michael D <michael.d.kinney@...>; Liu, Zhiguang
<zhiguang.liu@...>
Subject: 回复: [PATCHv3 1/1] MdePkg/UefiDevicePathLib: Add support
for
PEIMs

Mateusz:
To be compatible, I suggest to add one new
UefiDevicePathLibPeim.inf
for
PEIM module. It will be same to UefiDevicePathLibStandaloneMm.inf
except for
module type and base name.

The source file rename is the compatible change. It can be made.

Thanks
Liming
-----邮件原件-----
发件人: Mateusz Albecki <mateusz.albecki@...>
发送时间: 2022年7月1日 22:12
收件人: devel@edk2.groups.io
抄送: Mateusz Albecki <mateusz.albecki@...>; Michael D
Kinney
<michael.d.kinney@...>; Liming Gao
<gaoliming@...>; Zhiguang Liu <zhiguang.liu@...>
主题: [PATCHv3 1/1] MdePkg/UefiDevicePathLib: Add support for
PEIMs

DevicePathLib utilities are useful in PEI to locate the devices
which need an opal unlock on S3 resume. This commit reuses the
implementation
done
for standalone MM support and makes the StandaloneMm library
Base.

Signed-off-by: Mateusz Albecki <mateusz.albecki@...>

Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Liming Gao <gaoliming@...>
Cc: Zhiguang Liu <zhiguang.liu@...>

---
...athUtilitiesStandaloneMm.c => DevicePathUtilitiesBase.c} | 0
...icePathLibStandaloneMm.inf => UefiDevicePathLibBase.inf} | 6
+++--- MdePkg/MdePkg.dsc
|
2 +-
3 files changed, 4 insertions(+), 4 deletions(-) rename
MdePkg/Library/UefiDevicePathLib/{DevicePathUtilitiesStandaloneMm.
c
=>
DevicePathUtilitiesBase.c} (100%)
rename
MdePkg/Library/UefiDevicePathLib/{UefiDevicePathLibStandaloneMm.in
f
=>
UefiDevicePathLibBase.inf} (87%)

diff --git
a/MdePkg/Library/UefiDevicePathLib/DevicePathUtilitiesStandaloneMm.c
b/MdePkg/Library/UefiDevicePathLib/DevicePathUtilitiesBase.c
similarity index 100%
rename from
MdePkg/Library/UefiDevicePathLib/DevicePathUtilitiesStandaloneMm.c
rename to
MdePkg/Library/UefiDevicePathLib/DevicePathUtilitiesBase.c
diff --git
a/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibStandaloneMm.inf
b/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibBase.inf
similarity index 87%
rename from
MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibStandaloneMm.inf
rename to
MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibBase.inf
index 23fedf38b7..323043033f 100644
---
a/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibStandaloneMm.inf
+++ b/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibBase.inf
@@ -16,10 +16,10 @@
BASE_NAME = UefiDevicePathLib
MODULE_UNI_FILE = UefiDevicePathLib.uni
FILE_GUID =
D8E58437-44D3-4154-B7A7-EB794923EF12
- MODULE_TYPE = MM_STANDALONE
+ MODULE_TYPE = BASE
PI_SPECIFICATION_VERSION = 0x00010032
VERSION_STRING = 1.0
- LIBRARY_CLASS = DevicePathLib |
MM_STANDALONE MM_CORE_STANDALONE
+ LIBRARY_CLASS = DevicePathLib


#
@@ -28,7 +28,7 @@

[Sources]
DevicePathUtilities.c
- DevicePathUtilitiesStandaloneMm.c
+ DevicePathUtilitiesBase.c
DevicePathToText.c
DevicePathFromText.c
UefiDevicePathLib.c
diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc index
3d8874e647..9daee93523 100644
--- a/MdePkg/MdePkg.dsc
+++ b/MdePkg/MdePkg.dsc
@@ -111,7 +111,7 @@

MdePkg/Library/UefiDebugLibDebugPortProtocol/UefiDebugLibDebugPortPro
tocol.inf
MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf
MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
-
MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibStandaloneMm.inf
+ MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibBase.inf

MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptionalDevicePathPr
o
tocol.inf

MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDe
vicePathProtocol.inf
MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
--
2.28.0.windows.1

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














回复: [edk2-devel] [PATCH v3] BaseTools/Capsule: Add support for signtool to input subject name to sign capsule file

gaoliming
 

Jason:
Thanks for you to add the detail usage model in BZ 3928. I have no other
comments. Reviewed-by: Liming Gao <gaoliming@...>

Thanks
Liming
-----邮件原件-----
发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Lin, Jason1
发送时间: 2022年7月8日 19:42
收件人: devel@edk2.groups.io
抄送: Jason1 Lin <jason1.lin@...>; Bob Feng <bob.c.feng@...>;
Liming Gao <gaoliming@...>; Yuwei Chen
<yuwei.chen@...>; Michael D Kinney <michael.d.kinney@...>;
Dakota Chiang <dakota.chiang@...>
主题: [edk2-devel] [PATCH v3] BaseTools/Capsule: Add support for signtool
to
input subject name to sign capsule file

From: Jason1 Lin <jason1.lin@...>

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

Windows-based system using signtool.exe to sign the capsule.
Add the support to using "--subject-name" argument to assign
the subject name used to sign the capsule file.
This argument would pass to signtool.exe as a part of input
argument with "/n" flag.

NOTE: If using signtool.exe to sign capsule at least need to
choose one of "--pfx-file" and "--subject-name"
argument to input the value.

Signed-off-by: Jason1 Lin <jason1.lin@...>
Cc: Bob Feng <bob.c.feng@...>
Cc: Liming Gao <gaoliming@...>
Cc: Yuwei Chen <yuwei.chen@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Dakota Chiang <dakota.chiang@...>
---
BaseTools/Source/Python/Capsule/GenerateCapsule.py | 43
++++++++++++++++----
1 file changed, 34 insertions(+), 9 deletions(-)

diff --git a/BaseTools/Source/Python/Capsule/GenerateCapsule.py
b/BaseTools/Source/Python/Capsule/GenerateCapsule.py
index b8039db878..35435946c6 100644
--- a/BaseTools/Source/Python/Capsule/GenerateCapsule.py
+++ b/BaseTools/Source/Python/Capsule/GenerateCapsule.py
@@ -10,7 +10,7 @@
# keep the tool as simple as possible, it has the following limitations:

# * Do not support vendor code bytes in a capsule.

#

-# Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>

+# Copyright (c) 2018 - 2022, Intel Corporation. All rights reserved.<BR>

# SPDX-License-Identifier: BSD-2-Clause-Patent

#



@@ -38,11 +38,11 @@ from Common.Edk2.Capsule.FmpPayloadHeader
import FmpPayloadHeaderClass
# Globals for help information

#

__prog__ = 'GenerateCapsule'

-__version__ = '0.9'

-__copyright__ = 'Copyright (c) 2018, Intel Corporation. All rights
reserved.'

+__version__ = '0.10'

+__copyright__ = 'Copyright (c) 2022, Intel Corporation. All rights
reserved.'

__description__ = 'Generate a capsule.\n'



-def SignPayloadSignTool (Payload, ToolPath, PfxFile, Verbose = False):

+def SignPayloadSignTool (Payload, ToolPath, PfxFile, SubjectName, Verbose
=
False):

#

# Create a temporary directory

#

@@ -72,7 +72,10 @@ def SignPayloadSignTool (Payload, ToolPath, PfxFile,
Verbose = False):
Command = Command + '"{Path}" '.format (Path = os.path.join
(ToolPath,
'signtool.exe'))

Command = Command + 'sign /fd sha256 /p7ce DetachedSignedData
/p7co 1.2.840.113549.1.7.2 '

Command = Command + '/p7 {TempDir} '.format (TempDir =
TempDirectoryName)

- Command = Command + '/f {PfxFile} '.format (PfxFile = PfxFile)

+ if PfxFile is not None:

+ Command = Command + '/f {PfxFile} '.format (PfxFile = PfxFile)

+ if SubjectName is not None:

+ Command = Command + '/n {SubjectName} '.format
(SubjectName = SubjectName)

Command = Command + TempFileName

if Verbose:

print (Command)

@@ -105,7 +108,7 @@ def SignPayloadSignTool (Payload, ToolPath, PfxFile,
Verbose = False):
shutil.rmtree (TempDirectoryName)

return Signature



-def VerifyPayloadSignTool (Payload, CertData, ToolPath, PfxFile, Verbose
=
False):

+def VerifyPayloadSignTool (Payload, CertData, ToolPath, PfxFile,
SubjectName,
Verbose = False):

print ('signtool verify is not supported.')

raise ValueError ('GenerateCapsule: error: signtool verify is not
supported.')



@@ -249,6 +252,7 @@ if __name__ == '__main__':
HardwareInstance = ConvertJsonValue
(Config, 'HardwareInstance', ValidateUnsignedInteger, Required = False,
Default = 0)

MonotonicCount = ConvertJsonValue
(Config, 'MonotonicCount', ValidateUnsignedInteger, Required = False,
Default
= 0)

SignToolPfxFile = ConvertJsonValue (Config,
'SignToolPfxFile', os.path.expandvars, Required = False, Default = None,
Open
= True)

+ SignToolSubjectName = ConvertJsonValue (Config,
'SignToolSubjectName', os.path.expandvars, Required = False, Default =
None,
Open = True)

OpenSslSignerPrivateCertFile = ConvertJsonValue (Config,
'OpenSslSignerPrivateCertFile', os.path.expandvars, Required = False,
Default
= None, Open = True)

OpenSslOtherPublicCertFile = ConvertJsonValue (Config,
'OpenSslOtherPublicCertFile', os.path.expandvars, Required = False,
Default =
None, Open = True)

OpenSslTrustedPublicCertFile = ConvertJsonValue (Config,
'OpenSslTrustedPublicCertFile', os.path.expandvars, Required = False,
Default
= None, Open = True)

@@ -264,6 +268,7 @@ if __name__ == '__main__':
HardwareInstance,

UpdateImageIndex,

SignToolPfxFile,

+
SignToolSubjectName,


OpenSslSignerPrivateCertFile,


OpenSslOtherPublicCertFile,


OpenSslTrustedPublicCertFile,

@@ -303,6 +308,7 @@ if __name__ == '__main__':
UpdateImageIndex = ConvertJsonValue
(Config, 'UpdateImageIndex', ValidateUnsignedInteger, Required = False,
Default = 1)

MonotonicCount = ConvertJsonValue
(Config, 'MonotonicCount', ValidateUnsignedInteger, Required = False,
Default
= 0)

SignToolPfxFile = ConvertJsonValue (Config,
'SignToolPfxFile', os.path.expandvars, Required = False, Default = None,
Open
= True)

+ SignToolSubjectName = ConvertJsonValue (Config,
'SignToolSubjectName', os.path.expandvars, Required = False, Default =
None,
Open = True)

OpenSslSignerPrivateCertFile = ConvertJsonValue (Config,
'OpenSslSignerPrivateCertFile', os.path.expandvars, Required = False,
Default
= None, Open = True)

OpenSslOtherPublicCertFile = ConvertJsonValue (Config,
'OpenSslOtherPublicCertFile', os.path.expandvars, Required = False,
Default =
None, Open = True)

OpenSslTrustedPublicCertFile = ConvertJsonValue (Config,
'OpenSslTrustedPublicCertFile', os.path.expandvars, Required = False,
Default
= None, Open = True)

@@ -329,6 +335,7 @@ if __name__ == '__main__':
HardwareInstance,

UpdateImageIndex,

SignToolPfxFile,

+
SignToolSubjectName,


OpenSslSignerPrivateCertFile,


OpenSslOtherPublicCertFile,


OpenSslTrustedPublicCertFile,

@@ -348,6 +355,7 @@ if __name__ == '__main__':
"HardwareInstance":
str(PayloadDescriptor.HardwareInstance),

"UpdateImageIndex":
str(PayloadDescriptor.UpdateImageIndex),

"SignToolPfxFile":
str(PayloadDescriptor.SignToolPfxFile),

+ "SignToolSubjectName":
str(PayloadDescriptor.SignToolSubjectName),

"OpenSslSignerPrivateCertFile":
str(PayloadDescriptor.OpenSslSignerPrivateCertFile),

"OpenSslOtherPublicCertFile":
str(PayloadDescriptor.OpenSslOtherPublicCertFile),

"OpenSslTrustedPublicCertFile":
str(PayloadDescriptor.OpenSslTrustedPublicCertFile),

@@ -363,6 +371,8 @@ if __name__ == '__main__':
for PayloadField in PayloadSection:

if PayloadJsonDescriptorList[Index].SignToolPfxFile is None:

del PayloadField ['SignToolPfxFile']

+ if PayloadJsonDescriptorList[Index].SignToolSubjectName is
None:

+ del PayloadField ['SignToolSubjectName']

if
PayloadJsonDescriptorList[Index].OpenSslSignerPrivateCertFile is None:

del PayloadField ['OpenSslSignerPrivateCertFile']

if
PayloadJsonDescriptorList[Index].OpenSslOtherPublicCertFile is None:

@@ -402,6 +412,9 @@ if __name__ == '__main__':
if args.SignToolPfxFile:

print ('GenerateCapsule: error: Argument --pfx-file conflicts
with Argument -j')

sys.exit (1)

+ if args.SignToolSubjectName:

+ print ('GenerateCapsule: error: Argument --SubjectName
conflicts with Argument -j')

+ sys.exit (1)

if args.OpenSslSignerPrivateCertFile:

print ('GenerateCapsule: error: Argument
--signer-private-cert conflicts with Argument -j')

sys.exit (1)

@@ -425,6 +438,7 @@ if __name__ == '__main__':
HardwareInstance = 0,

UpdateImageIndex = 1,

SignToolPfxFile = None,

+ SignToolSubjectName = None,

OpenSslSignerPrivateCertFile = None,

OpenSslOtherPublicCertFile = None,

OpenSslTrustedPublicCertFile = None,

@@ -439,13 +453,15 @@ if __name__ == '__main__':
self.HardwareInstance = HardwareInstance

self.UpdateImageIndex = UpdateImageIndex

self.SignToolPfxFile = SignToolPfxFile

+ self.SignToolSubjectName = SignToolSubjectName

self.OpenSslSignerPrivateCertFile =
OpenSslSignerPrivateCertFile

self.OpenSslOtherPublicCertFile =
OpenSslOtherPublicCertFile

self.OpenSslTrustedPublicCertFile =
OpenSslTrustedPublicCertFile

self.SigningToolPath = SigningToolPath

self.DepexExp = DepexExp



- self.UseSignTool = self.SignToolPfxFile is not None

+ self.UseSignTool = (self.SignToolPfxFile is not None or

+ self.SignToolSubjectName is not
None)

self.UseOpenSsl = (self.OpenSslSignerPrivateCertFile is not
None and

self.OpenSslOtherPublicCertFile is
not None and

self.OpenSslTrustedPublicCertFile is
not None)

@@ -504,8 +520,9 @@ if __name__ == '__main__':
raise argparse.ArgumentTypeError
('--update-image-index must be an integer in range 0x0..0xff')



if self.UseSignTool:

- self.SignToolPfxFile.close()

- self.SignToolPfxFile = self.SignToolPfxFile.name

+ if self.SignToolPfxFile is not None:

+ self.SignToolPfxFile.close()

+ self.SignToolPfxFile = self.SignToolPfxFile.name

if self.UseOpenSsl:

self.OpenSslSignerPrivateCertFile.close()

self.OpenSslOtherPublicCertFile.close()

@@ -548,6 +565,7 @@ if __name__ == '__main__':

args.HardwareInstance,


args.UpdateImageIndex,

args.SignToolPfxFile,

+
args.SignToolSubjectName,


args.OpenSslSignerPrivateCertFile,


args.OpenSslOtherPublicCertFile,


args.OpenSslTrustedPublicCertFile,

@@ -590,6 +608,7 @@ if __name__ == '__main__':
Result + struct.pack ('<Q',
SinglePayloadDescriptor.MonotonicCount),

SinglePayloadDescriptor.SigningToolPath,

SinglePayloadDescriptor.SignToolPfxFile,

+
SinglePayloadDescriptor.SignToolSubjectName,

Verbose = args.Verbose

)

else:

@@ -671,6 +690,7 @@ if __name__ == '__main__':

args.HardwareInstance,


args.UpdateImageIndex,

args.SignToolPfxFile,

+
args.SignSubjectName,


args.OpenSslSignerPrivateCertFile,


args.OpenSslOtherPublicCertFile,


args.OpenSslTrustedPublicCertFile,

@@ -715,6 +735,7 @@ if __name__ == '__main__':

HardwareInstance,


UpdateImageIndex,


PayloadDescriptorList[Index].SignToolPfxFile,

+
PayloadDescriptorList[Index].SignToolSubjectName,


PayloadDescriptorList[Index].OpenSslSignerPrivateCertFile,


PayloadDescriptorList[Index].OpenSslOtherPublicCertFile,


PayloadDescriptorList[Index].OpenSslTrustedPublicCertFile,

@@ -753,6 +774,7 @@ if __name__ == '__main__':

HardwareInstance,


UpdateImageIndex,


PayloadDescriptorList[Index].SignToolPfxFile,

+
PayloadDescriptorList[Index].SignToolSubjectName,


PayloadDescriptorList[Index].OpenSslSignerPrivateCertFile,


PayloadDescriptorList[Index].OpenSslOtherPublicCertFile,


PayloadDescriptorList[Index].OpenSslTrustedPublicCertFile,

@@ -785,6 +807,7 @@ if __name__ == '__main__':

FmpAuthHeader.CertData,


SinglePayloadDescriptor.SigningToolPath,


SinglePayloadDescriptor.SignToolPfxFile,

+
SinglePayloadDescriptor.SignToolSubjectName,

Verbose =
args.Verbose

)

else:

@@ -968,6 +991,8 @@ if __name__ == '__main__':


parser.add_argument ("--pfx-file", dest='SignToolPfxFile',
type=argparse.FileType('rb'),

help="signtool PFX certificate filename.")

+ parser.add_argument ("--subject-name", dest='SignToolSubjectName',

+ help="signtool certificate subject name.")



parser.add_argument ("--signer-private-cert",
dest='OpenSslSignerPrivateCertFile', type=argparse.FileType('rb'),

help="OpenSSL signer private certificate
filename.")

--
2.37.0.windows.1



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


Re: [edk2-staging][PATCH v3] edk2/RedfishPkg: Update Redfish Platform Config Protocol

Chang, Abner
 

[AMD Official Use Only - General]

Thanks!
Reviewed-by: Abner Chang <abner.chang@...>

-----Original Message-----
From: Nickle Wang <nickle.wang@...>
Sent: Monday, July 25, 2022 11:24 AM
To: devel@edk2.groups.io
Cc: Chang, Abner <Abner.Chang@...>; Yang, Atom
<Atom.Yang@...>; Nick Ramirez <nramirez@...>
Subject: [edk2-staging][PATCH v3] edk2/RedfishPkg: Update Redfish
Platform Config Protocol

[CAUTION: External Email]

Update EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL and add array type
of
value support to EDKII_REDFISH_VALUE in order to support ordered list
op-code in HII. Modify corresponding function to support new type of
data structure.

Signed-off-by: Nickle Wang <nickle.wang@...>
Cc: Abner Chang <abner.chang@...>
Cc: Yang Atom <Atom.Yang@...>
Cc: Nick Ramirez <nramirez@...>
---
.../Protocol/EdkIIRedfishPlatformConfig.h | 301 +-
.../RedfishPlatformConfigDxe.c | 3087 ++++++++++-------
.../RedfishPlatformConfigDxe.h | 128 +-
.../RedfishPlatformConfigDxe.inf | 104 +-
.../RedfishPlatformConfigImpl.c | 2528 +++++++-------
.../RedfishPlatformConfigImpl.h | 571 +--
6 files changed, 3638 insertions(+), 3081 deletions(-)

diff --git a/RedfishPkg/Include/Protocol/EdkIIRedfishPlatformConfig.h
b/RedfishPkg/Include/Protocol/EdkIIRedfishPlatformConfig.h
index 895b010227..bbbab90b03 100644
--- a/RedfishPkg/Include/Protocol/EdkIIRedfishPlatformConfig.h
+++ b/RedfishPkg/Include/Protocol/EdkIIRedfishPlatformConfig.h
@@ -1,147 +1,154 @@
-/** @file
- This file defines the EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL
interface.
-
- (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef EDKII_REDFISH_PLATFORM_CONFIG_H_
-#define EDKII_REDFISH_PLATFORM_CONFIG_H_
-
-typedef struct _EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL;
-
-/**
- Definition of EDKII_REDFISH_TYPE_VALUE
- **/
-typedef union {
- INT64 Integer;
- BOOLEAN Boolean;
- CHAR8 *Buffer;
-} EDKII_REDFISH_TYPE_VALUE;
-
-/**
- Definition of EDKII_REDFISH_VALUE_TYPES
- **/
-typedef enum {
- REDFISH_VALUE_TYPE_UNKNOWN = 0,
- REDFISH_VALUE_TYPE_INTEGER,
- REDFISH_VALUE_TYPE_BOOLEAN,
- REDFISH_VALUE_TYPE_STRING,
- REDFISH_VALUE_TYPE_MAX
-} EDKII_REDFISH_VALUE_TYPES;
-
-/**
- Definition of EDKII_REDFISH_VALUE
- **/
-typedef struct {
- EDKII_REDFISH_VALUE_TYPES Type;
- EDKII_REDFISH_TYPE_VALUE Value;
-} EDKII_REDFISH_VALUE;
-
-/**
- Get Redfish value with the given Schema and Configure Language.
-
- @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
- @param[in] Schema The Redfish schema to query.
- @param[in] Version The Redfish version to query.
- @param[in] ConfigureLang The target value which match this configure
Language.
- @param[out] Value The returned value.
-
- @retval EFI_SUCCESS Value is returned successfully.
- @retval Others Some error happened.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_VALUE) (
- IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
- IN CHAR8 *Schema,
- IN CHAR8 *Version,
- IN EFI_STRING ConfigureLang,
- OUT EDKII_REDFISH_VALUE *Value
- );
-
-/**
- Set Redfish value with the given Schema and Configure Language.
-
- @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
- @param[in] Schema The Redfish schema to query.
- @param[in] Version The Redfish version to query.
- @param[in] ConfigureLang The target value which match this configure
Language.
- @param[in] Value The value to set.
-
- @retval EFI_SUCCESS Value is returned successfully.
- @retval Others Some error happened.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_SET_VALUE) (
- IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
- IN CHAR8 *Schema,
- IN CHAR8 *Version,
- IN EFI_STRING ConfigureLang,
- IN EDKII_REDFISH_VALUE Value
- );
-
-/**
- Get the list of Configure Language from platform configuration by the given
Schema and Pattern.
-
- @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
- @param[in] Schema The Redfish schema to query.
- @param[in] Version The Redfish version to query.
- @param[in] Pattern The target Configure Language pattern.
- @param[out] ConfigureLangList The list of Configure Language.
- @param[out] Count The number of Configure Language in
ConfigureLangList.
-
- @retval EFI_SUCCESS ConfigureLangList is returned successfully.
- @retval Others Some error happened.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_CONFIG_LANG) (
- IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
- IN CHAR8 *Schema,
- IN CHAR8 *Version,
- IN EFI_STRING Pattern,
- OUT EFI_STRING **ConfigureLangList,
- OUT UINTN *Count
- );
-
-
-/**
- Get the list of supported Redfish schema from platform configuration on
the give HII handle.
-
- @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
- @param[in] HiiHandle The target handle to search. If handle is NULL,
- this function returns all schema from HII database.
- @param[out] SupportedSchema The supported schema list which is
separated by ';'.
- For example: "x-uefi-redfish-Memory.v1_7_1;x-uefi-
redfish-Boot.v1_0_1"
- The SupportedSchema is allocated by the callee. It's caller's
- responsibility to free this buffer using FreePool().
-
- @retval EFI_SUCCESS Schema is returned successfully.
- @retval Others Some error happened.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_SUPPORTED_SCHEMA)
(
- IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
- IN EFI_HII_HANDLE HiiHandle, OPTIONAL
- OUT CHAR8 **SupportedSchema
- );
-
-struct _EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL {
- EDKII_REDFISH_PLATFORM_CONFIG_GET_VALUE GetValue;
- EDKII_REDFISH_PLATFORM_CONFIG_SET_VALUE SetValue;
- EDKII_REDFISH_PLATFORM_CONFIG_GET_CONFIG_LANG
GetConfigureLang;
- EDKII_REDFISH_PLATFORM_CONFIG_GET_SUPPORTED_SCHEMA
GetSupportedSchema;
-};
-
-extern EFI_GUID gEdkIIRedfishPlatformConfigProtocolGuid;
-
-#endif
+/** @file
+ This file defines the EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL
interface.
+
+ (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef EDKII_REDFISH_PLATFORM_CONFIG_H_
+#define EDKII_REDFISH_PLATFORM_CONFIG_H_
+
+typedef struct _EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL;
+
+/**
+ Definition of EDKII_REDFISH_TYPE_VALUE
+ **/
+typedef union {
+ INT64 Integer;
+ BOOLEAN Boolean;
+ CHAR8 *Buffer;
+ CHAR8 **StringArray;
+ INT64 *IntegerArray;
+ BOOLEAN *BooleanArray;
+} EDKII_REDFISH_TYPE_VALUE;
+
+/**
+ Definition of EDKII_REDFISH_VALUE_TYPES
+ **/
+typedef enum {
+ REDFISH_VALUE_TYPE_UNKNOWN = 0,
+ REDFISH_VALUE_TYPE_INTEGER,
+ REDFISH_VALUE_TYPE_BOOLEAN,
+ REDFISH_VALUE_TYPE_STRING,
+ REDFISH_VALUE_TYPE_STRING_ARRAY,
+ REDFISH_VALUE_TYPE_INTEGER_ARRAY,
+ REDFISH_VALUE_TYPE_BOOLEAN_ARRAY,
+ REDFISH_VALUE_TYPE_MAX
+} EDKII_REDFISH_VALUE_TYPES;
+
+/**
+ Definition of EDKII_REDFISH_VALUE
+ **/
+typedef struct {
+ EDKII_REDFISH_VALUE_TYPES Type;
+ EDKII_REDFISH_TYPE_VALUE Value;
+ UINTN ArrayCount;
+} EDKII_REDFISH_VALUE;
+
+/**
+ Get Redfish value with the given Schema and Configure Language.
+
+ @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+ @param[in] Schema The Redfish schema to query.
+ @param[in] Version The Redfish version to query.
+ @param[in] ConfigureLang The target value which match this configure
Language.
+ @param[out] Value The returned value.
+
+ @retval EFI_SUCCESS Value is returned successfully.
+ @retval Others Some error happened.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_VALUE) (
+ IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+ IN CHAR8 *Schema,
+ IN CHAR8 *Version,
+ IN EFI_STRING ConfigureLang,
+ OUT EDKII_REDFISH_VALUE *Value
+ );
+
+/**
+ Set Redfish value with the given Schema and Configure Language.
+
+ @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+ @param[in] Schema The Redfish schema to query.
+ @param[in] Version The Redfish version to query.
+ @param[in] ConfigureLang The target value which match this configure
Language.
+ @param[in] Value The value to set.
+
+ @retval EFI_SUCCESS Value is returned successfully.
+ @retval Others Some error happened.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_SET_VALUE) (
+ IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+ IN CHAR8 *Schema,
+ IN CHAR8 *Version,
+ IN EFI_STRING ConfigureLang,
+ IN EDKII_REDFISH_VALUE Value
+ );
+
+/**
+ Get the list of Configure Language from platform configuration by the
given Schema and RegexPattern.
+
+ @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+ @param[in] Schema The Redfish schema to query.
+ @param[in] Version The Redfish version to query.
+ @param[in] RegexPattern The target Configure Language pattern.
This is used for regular expression matching.
+ @param[out] ConfigureLangList The list of Configure Language.
+ @param[out] Count The number of Configure Language in
ConfigureLangList.
+
+ @retval EFI_SUCCESS ConfigureLangList is returned successfully.
+ @retval Others Some error happened.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_CONFIG_LANG) (
+ IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+ IN CHAR8 *Schema,
+ IN CHAR8 *Version,
+ IN EFI_STRING RegexPattern,
+ OUT EFI_STRING **ConfigureLangList,
+ OUT UINTN *Count
+ );
+
+
+/**
+ Get the list of supported Redfish schema from platform configuration on
the give HII handle.
+
+ @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+ @param[in] HiiHandle The target handle to search. If handle is NULL,
+ this function returns all schema from HII database.
+ @param[out] SupportedSchema The supported schema list which is
separated by ';'.
+ For example: "x-uefi-redfish-Memory.v1_7_1;x-uefi-
redfish-Boot.v1_0_1"
+ The SupportedSchema is allocated by the callee. It's
caller's
+ responsibility to free this buffer using FreePool().
+
+ @retval EFI_SUCCESS Schema is returned successfully.
+ @retval Others Some error happened.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_SUPPORTED_SCHEMA)
(
+ IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+ IN EFI_HII_HANDLE HiiHandle, OPTIONAL
+ OUT CHAR8 **SupportedSchema
+ );
+
+struct _EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL {
+ EDKII_REDFISH_PLATFORM_CONFIG_GET_VALUE GetValue;
+ EDKII_REDFISH_PLATFORM_CONFIG_SET_VALUE SetValue;
+ EDKII_REDFISH_PLATFORM_CONFIG_GET_CONFIG_LANG
GetConfigureLang;
+ EDKII_REDFISH_PLATFORM_CONFIG_GET_SUPPORTED_SCHEMA
GetSupportedSchema;
+};
+
+extern EFI_GUID gEdkIIRedfishPlatformConfigProtocolGuid;
+
+#endif
diff --git
a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
index 67818cccd2..971035f27d 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
@@ -1,1304 +1,1783 @@
-/** @file
-
- The implementation of EDKII Redfidh Platform Config Protocol.
-
- (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "RedfishPlatformConfigDxe.h"
-#include "RedfishPlatformConfigImpl.h"
-
-REDFISH_PLATFORM_CONFIG_PRIVATE *mRedfishPlatformConfigPrivate =
NULL;
-
-/**
- Compare two value in HII statement format.
-
- @param[in] Value1 Firt value to compare.
- @param[in] Value2 Second value to be compared.
-
- @retval UINTN 0 is retuned when two values are equal.
- 1 is returned when first value is greater than second value.
- -1 is returned when second value is greater than first value.
-
-**/
-UINTN
-CompareHiiStatementValue (
- IN HII_STATEMENT_VALUE *Value1,
- IN HII_STATEMENT_VALUE *Value2
- )
-{
- INTN Result;
- UINT64 Data1;
- UINT64 Data2;
-
- if (Value1 == NULL || Value2 == NULL) {
- return 0xFF;
- }
-
- switch (Value1->Type) {
- case EFI_IFR_TYPE_NUM_SIZE_8:
- Data1 = Value1->Value.u8;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_16:
- Data1 = Value1->Value.u16;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_32:
- Data1 = Value1->Value.u32;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_64:
- Data1 = Value1->Value.u64;
- break;
- case EFI_IFR_TYPE_BOOLEAN:
- Data1 = (Value1->Value.b ? 1 : 0);
- break;
- default:
- return 0xFF;
- }
-
- switch (Value2->Type) {
- case EFI_IFR_TYPE_NUM_SIZE_8:
- Data2 = Value2->Value.u8;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_16:
- Data2 = Value2->Value.u16;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_32:
- Data2 = Value2->Value.u32;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_64:
- Data2 = Value2->Value.u64;
- break;
- case EFI_IFR_TYPE_BOOLEAN:
- Data2 = (Value2->Value.b ? 1 : 0);
- break;
- default:
- return 0xFF;
- }
-
- Result = (Data1 == Data2 ? 0 : (Data1 > Data2 ? 1 : -1));
-
- return Result;
-}
-
-/**
- Convert HII value to the string in HII one-of opcode.
-
- @param[in] Statement Statement private instance
-
- @retval EFI_STRING_ID The string ID in HII database.
- 0 is returned when something goes wrong.
-
-**/
-EFI_STRING_ID
-HiiValueToOneOfOptionStringId (
- IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement
- )
-{
- LIST_ENTRY *Link;
- HII_QUESTION_OPTION *Option;
-
- if (Statement->HiiStatement->Operand != EFI_IFR_ONE_OF_OP) {
- return 0;
- }
-
- if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
- return 0;
- }
-
- Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
- while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
- Option = HII_QUESTION_OPTION_FROM_LINK (Link);
-
- if (CompareHiiStatementValue (&Statement->HiiStatement->Value,
&Option->Value) == 0) {
- return Option->Text;
- }
-
- Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
- }
-
- return 0;
-}
-
-/**
- Convert HII string to the value in HII one-of opcode.
-
- @param[in] Statement Statement private instance
- @param[in] Schema Schema string
- @param[in] HiiString Input string
- @param[out] Value Value returned
-
- @retval EFI_SUCCESS HII value is returned successfully.
- @retval Others Errors occur
-
-**/
-EFI_STATUS
-HiiStringToOneOfOptionValue (
- IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement,
- IN CHAR8 *Schema,
- IN EFI_STRING HiiString,
- OUT HII_STATEMENT_VALUE *Value
- )
-{
- LIST_ENTRY *Link;
- HII_QUESTION_OPTION *Option;
- EFI_STRING TmpString;
- BOOLEAN Found;
-
- if (Statement == NULL || IS_EMPTY_STRING (HiiString) || Value == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (Statement->HiiStatement->Operand != EFI_IFR_ONE_OF_OP) {
- return EFI_UNSUPPORTED;
- }
-
- if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
- return EFI_NOT_FOUND;
- }
-
- Found = FALSE;
- Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
- while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
- Option = HII_QUESTION_OPTION_FROM_LINK (Link);
-
- TmpString = HiiGetRedfishString (Statement->ParentForm-
ParentFormset->HiiHandle, Schema, Option->Text);
- if (TmpString != NULL) {
- if (StrCmp (TmpString, HiiString) == 0) {
- CopyMem (Value, &Option->Value, sizeof (HII_STATEMENT_VALUE));
- Found = TRUE;
- }
- FreePool (TmpString);
- }
-
- if (Found) {
- return EFI_SUCCESS;
- }
-
- Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
- }
-
- return EFI_NOT_FOUND;
-}
-
-/**
- Convert HII value to numeric value in Redfish format.
-
- @param[in] Value Value to be converted.
- @param[out] RedfishValue Value in Redfish format.
-
- @retval EFI_SUCCESS Redfish value is returned successfully.
- @retval Others Errors occur
-
-**/
-EFI_STATUS
-HiiValueToRedfishNumeric (
- IN HII_STATEMENT_VALUE *Value,
- OUT EDKII_REDFISH_VALUE *RedfishValue
- )
-{
- if (Value == NULL || RedfishValue == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- switch (Value->Type) {
- case EFI_IFR_TYPE_NUM_SIZE_8:
- RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
- RedfishValue->Value.Integer = (INT64)Value->Value.u8;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_16:
- RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
- RedfishValue->Value.Integer = (INT64)Value->Value.u16;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_32:
- RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
- RedfishValue->Value.Integer = (INT64)Value->Value.u32;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_64:
- RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
- RedfishValue->Value.Integer = (INT64)Value->Value.u64;
- break;
- case EFI_IFR_TYPE_BOOLEAN:
- RedfishValue->Type = REDFISH_VALUE_TYPE_BOOLEAN;
- RedfishValue->Value.Boolean = Value->Value.b;
- break;
- default:
- RedfishValue->Type = REDFISH_VALUE_TYPE_UNKNOWN;
- break;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Convert numeric value in Redfish format to HII value.
-
- @param[in] RedfishValue Value in Redfish format to be converted.
- @param[out] Value HII value returned.
-
- @retval EFI_SUCCESS HII value is returned successfully.
- @retval Others Errors occur
-
-**/
-EFI_STATUS
-RedfishNumericToHiiValue (
- IN EDKII_REDFISH_VALUE *RedfishValue,
- OUT HII_STATEMENT_VALUE *Value
- )
-{
- if (Value == NULL || RedfishValue == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- switch (RedfishValue->Type) {
- case REDFISH_VALUE_TYPE_INTEGER:
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
- Value->Value.u64 = (UINT64)RedfishValue->Value.Integer;
- break;
- case REDFISH_VALUE_TYPE_BOOLEAN:
- Value->Type = EFI_IFR_TYPE_BOOLEAN;
- Value->Value.b = RedfishValue->Value.Boolean;
- break;
- default:
- Value->Type = EFI_IFR_TYPE_UNDEFINED;
- break;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Return the full Redfish schema string from the given Schema and Version.
-
- Returned schema string is: Schema + '.' + Version
-
- @param[in] Schema Schema string
- @param[in] Version Schema version string
-
- @retval CHAR8 * Schema string. NULL when errors occur.
-
-**/
-CHAR8 *
-GetFullSchemaString (
- IN CHAR8 *Schema,
- IN CHAR8 *Version
- )
-{
- UINTN Size;
- CHAR8 *FullName;
-
- if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version)) {
- return NULL;
- }
-
- Size = AsciiStrSize(CONFIGURE_LANGUAGE_PREFIX) + AsciiStrSize (Schema)
+ AsciiStrSize (Version);
-
- FullName = AllocatePool (Size);
- if (FullName == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, out-of-resource\n", __FUNCTION__));
- return NULL;
- }
-
- AsciiSPrint (FullName, Size, "%a%a.%a", CONFIGURE_LANGUAGE_PREFIX,
Schema, Version);
-
- return FullName;
-}
-
-/**
- Common implementation to get statement private instance.
-
- @param[in] RedfishPlatformConfigPrivate Private instance.
- @param[in] Schema Redfish schema string.
- @param[in] ConfigureLang Configure language that refers to this
statement.
- @param[out] Statement Statement instance
-
- @retval EFI_SUCCESS HII value is returned successfully.
- @retval Others Errors occur
-
-**/
-EFI_STATUS
-RedfishPlatformConfigGetStatementCommon (
- IN REDFISH_PLATFORM_CONFIG_PRIVATE
*RedfishPlatformConfigPrivate,
- IN CHAR8 *Schema,
- IN EFI_STRING ConfigureLang,
- OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE **Statement
- )
-{
- EFI_STATUS Status;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
-
- if (RedfishPlatformConfigPrivate == NULL || IS_EMPTY_STRING (Schema)
|| IS_EMPTY_STRING (ConfigureLang) || Statement == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- *Statement = NULL;
-
- Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
&RedfishPlatformConfigPrivate->PendingList);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
__FUNCTION__, Status));
- return Status;
- }
-
- TargetStatement = GetStatementPrivateByConfigureLang
(&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
- if (TargetStatement == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, No match HII statement is found by the
given %s in schema %a\n", __FUNCTION__, ConfigureLang, Schema));
- return EFI_NOT_FOUND;
- }
-
- //
- // Find current HII question value.
- //
- Status = GetQuestionValue (
- TargetStatement->ParentForm->ParentFormset->HiiFormSet,
- TargetStatement->ParentForm->HiiForm,
- TargetStatement->HiiStatement,
- GetSetValueWithHiiDriver
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to get question current value: %r\n",
__FUNCTION__, Status));
- return Status;
- }
-
-
- if (TargetStatement->HiiStatement->Value.Type ==
EFI_IFR_TYPE_UNDEFINED) {
- return EFI_DEVICE_ERROR;
- }
-
- //
- // Return Value.
- //
- *Statement = TargetStatement;
-
- return EFI_SUCCESS;
-}
-
-/**
- Get Redfish value with the given Schema and Configure Language.
-
- @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
- @param[in] Schema The Redfish schema to query.
- @param[in] Version The Redfish version to query.
- @param[in] ConfigureLang The target value which match this configure
Language.
- @param[out] Value The returned value.
-
- @retval EFI_SUCCESS Value is returned successfully.
- @retval Others Some error happened.
-
-**/
-EFI_STATUS
-EFIAPI
-RedfishPlatformConfigProtocolGetValue (
- IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
- IN CHAR8 *Schema,
- IN CHAR8 *Version,
- IN EFI_STRING ConfigureLang,
- OUT EDKII_REDFISH_VALUE *Value
- )
-{
- EFI_STATUS Status;
- REDFISH_PLATFORM_CONFIG_PRIVATE
*RedfishPlatformConfigPrivate;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
- EFI_STRING_ID StringId;
- CHAR8 *FullSchema;
- EFI_STRING HiiString;
- UINTN Size;
-
- if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
(Version) || IS_EMPTY_STRING (ConfigureLang) || Value == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- RedfishPlatformConfigPrivate =
REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
- Value->Type = REDFISH_VALUE_TYPE_UNKNOWN;
- FullSchema = NULL;
- HiiString = NULL;
-
- FullSchema = GetFullSchemaString (Schema, Version);
- if (FullSchema == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Status = RedfishPlatformConfigGetStatementCommon
(RedfishPlatformConfigPrivate, FullSchema, ConfigureLang,
&TargetStatement);
- if (EFI_ERROR (Status)) {
- goto RELEASE_RESOURCE;
- }
-
- switch (TargetStatement->HiiStatement->Operand) {
- case EFI_IFR_ONE_OF_OP:
- StringId = HiiValueToOneOfOptionStringId (TargetStatement);
- if (StringId == 0) {
- ASSERT (FALSE);
- Status = EFI_DEVICE_ERROR;
- goto RELEASE_RESOURCE;
- }
-
- HiiString = HiiGetRedfishString (TargetStatement->ParentForm-
ParentFormset->HiiHandle, FullSchema, StringId);
- if (HiiString == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, Can not find string ID: 0x%x with %a\n",
__FUNCTION__, StringId, FullSchema));
- Status = EFI_NOT_FOUND;
- goto RELEASE_RESOURCE;
- }
-
- Size = StrLen (HiiString) + 1;
- Value->Value.Buffer = AllocatePool (Size);
- if (Value->Value.Buffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto RELEASE_RESOURCE;
- }
-
- UnicodeStrToAsciiStrS (HiiString, Value->Value.Buffer, Size);
- Value->Type = REDFISH_VALUE_TYPE_STRING;
-
- break;
- case EFI_IFR_STRING_OP:
- if (TargetStatement->HiiStatement->Value.Type !=
EFI_IFR_TYPE_STRING) {
- ASSERT (FALSE);
- Status = EFI_DEVICE_ERROR;
- goto RELEASE_RESOURCE;
- }
-
- Value->Type = REDFISH_VALUE_TYPE_STRING;
- Value->Value.Buffer = AllocateCopyPool (StrSize ((CHAR16
*)TargetStatement->HiiStatement->Value.Buffer), TargetStatement-
HiiStatement->Value.Buffer);
- if (Value->Value.Buffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto RELEASE_RESOURCE;
- }
- break;
- case EFI_IFR_CHECKBOX_OP:
- case EFI_IFR_NUMERIC_OP:
- Status = HiiValueToRedfishNumeric (&TargetStatement->HiiStatement-
Value, Value);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to convert HII value to Redfish
value: %r\n", __FUNCTION__, Status));
- goto RELEASE_RESOURCE;
- }
- break;
- default:
- DEBUG ((DEBUG_ERROR, "%a, catch unsupported type: 0x%x! Please
contact with author if we need to support this type.\n", __FUNCTION__,
TargetStatement->HiiStatement->Operand));
- ASSERT (FALSE);
- Status = EFI_UNSUPPORTED;
- goto RELEASE_RESOURCE;
- }
-
-RELEASE_RESOURCE:
-
- if (FullSchema != NULL) {
- FreePool (FullSchema);
- }
-
- if (HiiString != NULL) {
- FreePool (HiiString);
- }
-
- return Status;
-}
-
-/**
- Function to save question value into HII database.
-
- @param[in] HiiFormset HII form-set instance
- @param[in] HiiForm HII form instance
- @param[in] HiiStatement HII statement that keeps new value.
- @param[in] Value New value to applyu.
-
- @retval EFI_SUCCESS HII value is returned successfully.
- @retval Others Errors occur
-
-**/
-EFI_STATUS
-RedfishPlatformConfigSaveQuestionValue (
- IN HII_FORMSET *HiiFormset,
- IN HII_FORM *HiiForm,
- IN HII_STATEMENT *HiiStatement,
- IN HII_STATEMENT_VALUE *Value
- )
-{
- EFI_STATUS Status;
-
- if (HiiFormset == NULL || HiiForm == NULL || HiiStatement == NULL ||
Value == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- Status = SetQuestionValue (
- HiiFormset,
- HiiForm,
- HiiStatement,
- Value
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to set question value: %r\n",
__FUNCTION__, Status));
- return Status;
- }
-
- Status = SubmitForm (HiiFormset, HiiForm);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to submit form: %r\n",
__FUNCTION__, Status));
- return Status;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Common implementation to set statement private instance.
-
- @param[in] RedfishPlatformConfigPrivate Private instance.
- @param[in] Schema Redfish schema string.
- @param[in] ConfigureLang Configure language that refers to this
statement.
- @param[in] Statement Statement instance
-
- @retval EFI_SUCCESS HII value is returned successfully.
- @retval Others Errors occur
-
-**/
-EFI_STATUS
-RedfishPlatformConfigSetStatementCommon (
- IN REDFISH_PLATFORM_CONFIG_PRIVATE
*RedfishPlatformConfigPrivate,
- IN CHAR8 *Schema,
- IN EFI_STRING ConfigureLang,
- IN HII_STATEMENT_VALUE *StatementValue
- )
-{
- EFI_STATUS Status;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
- EFI_STRING TempBuffer;
-
- if (RedfishPlatformConfigPrivate == NULL || IS_EMPTY_STRING (Schema)
|| IS_EMPTY_STRING (ConfigureLang) || StatementValue == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- TempBuffer = NULL;
-
- Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
&RedfishPlatformConfigPrivate->PendingList);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
__FUNCTION__, Status));
- return Status;
- }
-
- TargetStatement = GetStatementPrivateByConfigureLang
(&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
- if (TargetStatement == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, No match HII statement is found by the
given %s in schema %a\n", __FUNCTION__, ConfigureLang, Schema));
- return EFI_NOT_FOUND;
- }
-
- if (StatementValue->Type != TargetStatement->HiiStatement->Value.Type)
{
- //
- // We treat one-of type as string in Redfish. But one-of statement is not
- // in string format from HII point of view. Do a patch here.
- //
- if (TargetStatement->HiiStatement->Operand == EFI_IFR_ONE_OF_OP
&& StatementValue->Type == EFI_IFR_TYPE_STRING) {
- TempBuffer = AllocatePool (StatementValue->BufferLen * sizeof
(CHAR16));
- if (TempBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- AsciiStrToUnicodeStrS (StatementValue->Buffer, TempBuffer,
StatementValue->BufferLen);
- FreePool (StatementValue->Buffer);
- StatementValue->Buffer = NULL;
- StatementValue->BufferLen = 0;
-
- Status = HiiStringToOneOfOptionValue (TargetStatement, Schema,
TempBuffer, StatementValue);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to find option value by the given
%s\n", __FUNCTION__, TempBuffer));
- FreePool (TempBuffer);
- return EFI_NOT_FOUND;
- }
-
- FreePool (TempBuffer);
- } else if (TargetStatement->HiiStatement->Operand ==
EFI_IFR_NUMERIC_OP && StatementValue->Type ==
EFI_IFR_TYPE_NUM_SIZE_64) {
- //
- // Redfish only has numeric value type and it does not care about the
value size.
- // Do a patch here so we have proper value size applied.
- //
- StatementValue->Type = TargetStatement->HiiStatement->Value.Type;
- } else {
- DEBUG ((DEBUG_ERROR, "%a, catch value type mismatch! input type:
0x%x but target value type: 0x%x\n", __FUNCTION__, StatementValue-
Type, TargetStatement->HiiStatement->Value.Type));
- ASSERT (FALSE);
- }
- }
-
- Status = RedfishPlatformConfigSaveQuestionValue (
- TargetStatement->ParentForm->ParentFormset->HiiFormSet,
- TargetStatement->ParentForm->HiiForm,
- TargetStatement->HiiStatement,
- StatementValue
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to save question value: %r\n",
__FUNCTION__, Status));
- return Status;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Set Redfish value with the given Schema and Configure Language.
-
- @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
- @param[in] Schema The Redfish schema to query.
- @param[in] Version The Redfish version to query.
- @param[in] ConfigureLang The target value which match this configure
Language.
- @param[in] Value The value to set.
-
- @retval EFI_SUCCESS Value is returned successfully.
- @retval Others Some error happened.
-
-**/
-EFI_STATUS
-EFIAPI
-RedfishPlatformConfigProtocolSetValue (
- IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
- IN CHAR8 *Schema,
- IN CHAR8 *Version,
- IN EFI_STRING ConfigureLang,
- IN EDKII_REDFISH_VALUE Value
- )
-{
- EFI_STATUS Status;
- REDFISH_PLATFORM_CONFIG_PRIVATE
*RedfishPlatformConfigPrivate;
- CHAR8 *FullSchema;
- HII_STATEMENT_VALUE NewValue;
-
- if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
(Version) || IS_EMPTY_STRING (ConfigureLang)) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (Value.Type == REDFISH_VALUE_TYPE_UNKNOWN || Value.Type >=
REDFISH_VALUE_TYPE_MAX) {
- return EFI_INVALID_PARAMETER;
- }
-
- RedfishPlatformConfigPrivate =
REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
- FullSchema = NULL;
-
- FullSchema = GetFullSchemaString (Schema, Version);
- if (FullSchema == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- ZeroMem (&NewValue, sizeof (HII_STATEMENT_VALUE));
-
- switch (Value.Type) {
- case REDFISH_VALUE_TYPE_INTEGER:
- case REDFISH_VALUE_TYPE_BOOLEAN:
- Status = RedfishNumericToHiiValue (&Value, &NewValue);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to convert Redfish value to Hii
value: %r\n", __FUNCTION__, Status));
- goto RELEASE_RESOURCE;
- }
- break;
- case REDFISH_VALUE_TYPE_STRING:
- NewValue.Type = EFI_IFR_TYPE_STRING;
- NewValue.BufferLen = (UINT16)AsciiStrSize (Value.Value.Buffer);
- NewValue.Buffer = AllocateCopyPool (NewValue.BufferLen,
Value.Value.Buffer);
- if (NewValue.Buffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto RELEASE_RESOURCE;
- }
- break;
- default:
- ASSERT (FALSE);
- break;
- }
-
- Status = RedfishPlatformConfigSetStatementCommon
(RedfishPlatformConfigPrivate, FullSchema, ConfigureLang, &NewValue);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to set value to statement: %r\n",
__FUNCTION__, Status));
- }
-
-RELEASE_RESOURCE:
-
- if (FullSchema != NULL) {
- FreePool (FullSchema);
- }
-
- return Status;
-}
-
-/**
- Get the list of Configure Language from platform configuration by the given
Schema and Pattern.
-
- @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
- @param[in] Schema The Redfish schema to query.
- @param[in] Version The Redfish version to query.
- @param[in] Pattern The target Configure Language pattern.
- @param[out] ConfigureLangList The list of Configure Language.
- @param[out] Count The number of Configure Language in
ConfigureLangList.
-
- @retval EFI_SUCCESS ConfigureLangList is returned successfully.
- @retval Others Some error happened.
-
-**/
-EFI_STATUS
-EFIAPI
-RedfishPlatformConfigProtocolGetConfigureLang (
- IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
- IN CHAR8 *Schema,
- IN CHAR8 *Version,
- IN EFI_STRING Pattern,
- OUT EFI_STRING **ConfigureLangList,
- OUT UINTN *Count
- )
-{
- REDFISH_PLATFORM_CONFIG_PRIVATE
*RedfishPlatformConfigPrivate;
- EFI_STATUS Status;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST StatementList;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF *StatementRef;
- LIST_ENTRY *NextLink;
- EFI_STRING TmpString;
- EFI_STRING *TmpConfigureLangList;
- UINTN Index;
- CHAR8 *FullSchema;
-
- if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
(Version) || Count == NULL || ConfigureLangList == NULL ||
IS_EMPTY_STRING (Pattern)) {
- return EFI_INVALID_PARAMETER;
- }
-
- *Count = 0;
- *ConfigureLangList = NULL;
- FullSchema = NULL;
- RedfishPlatformConfigPrivate =
REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
-
- Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
&RedfishPlatformConfigPrivate->PendingList);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
__FUNCTION__, Status));
- return Status;
- }
-
- FullSchema = GetFullSchemaString (Schema, Version);
- if (FullSchema == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Status = GetStatementPrivateByConfigureLangRegex (
- RedfishPlatformConfigPrivate->RegularExpressionProtocol,
- &RedfishPlatformConfigPrivate->FormsetList,
- FullSchema,
- Pattern,
- &StatementList
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a,
GetStatementPrivateByConfigureLangRegex failure: %r\n", __FUNCTION__,
Status));
- goto RELEASE_RESOURCE;
- }
-
- if (!IsListEmpty (&StatementList.StatementList)) {
-
- TmpConfigureLangList = AllocateZeroPool (sizeof (CHAR16 *) *
StatementList.Count);
- if (TmpConfigureLangList == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto RELEASE_RESOURCE;
- }
-
- Index = 0;
- NextLink = GetFirstNode (&StatementList.StatementList);
- while (!IsNull (&StatementList.StatementList, NextLink)) {
- StatementRef =
REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
- NextLink = GetNextNode (&StatementList.StatementList, NextLink);
-
- ASSERT (StatementRef->Statement->Description != 0);
- if (StatementRef->Statement->Description != 0) {
- TmpString = HiiGetRedfishString (StatementRef->Statement-
ParentForm->ParentFormset->HiiHandle, FullSchema, StatementRef-
Statement->Description);
- ASSERT (TmpString != NULL);
- if (TmpString != NULL) {
- TmpConfigureLangList[Index] = AllocateCopyPool (StrSize (TmpString),
TmpString);
- ASSERT (TmpConfigureLangList[Index] != NULL);
- FreePool (TmpString);
- ++Index;
- }
- }
- }
- }
-
- *Count = StatementList.Count;
- *ConfigureLangList = TmpConfigureLangList;
-
-RELEASE_RESOURCE:
-
- if (FullSchema != NULL) {
- FreePool (FullSchema);
- }
-
- ReleaseStatementList (&StatementList);
-
- return Status;
-}
-
-
-/**
- Get the list of supported Redfish schema from paltform configuration on
give HII handle.
-
- @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
- @param[in] HiiHandle The target handle to search. If handle is NULL,
- this function return all schema from HII database.
- @param[out] SupportedSchema The supported schema list which is
separated by ';'.
- The SupportedSchema is allocated by the callee. It's caller's
- responsibility to free this buffer using FreePool().
-
- @retval EFI_SUCCESS Schema is returned successfully.
- @retval Others Some error happened.
-
-**/
-EFI_STATUS
-EFIAPI
-RedfishPlatformConfigProtocolGetSupportedSchema (
- IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
- IN EFI_HII_HANDLE HiiHandle, OPTIONAL
- OUT CHAR8 **SupportedSchema
- )
-{
- REDFISH_PLATFORM_CONFIG_PRIVATE
*RedfishPlatformConfigPrivate;
- EFI_STATUS Status;
- LIST_ENTRY *HiiFormsetLink;
- LIST_ENTRY *HiiFormsetNextLink;
- REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
- UINTN Index;
- UINTN StringSize;
- CHAR8 *StringBuffer;
- UINTN StringIndex;
-
- if (This == NULL || SupportedSchema == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- *SupportedSchema = NULL;
-
- RedfishPlatformConfigPrivate =
REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
-
- Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
&RedfishPlatformConfigPrivate->PendingList);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
__FUNCTION__, Status));
- return Status;
- }
-
- if (IsListEmpty (&RedfishPlatformConfigPrivate->FormsetList)) {
- return EFI_NOT_FOUND;
- }
-
- //
- // Calculate for string buffer size.
- //
- StringSize = 0;
- HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate-
FormsetList);
- while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList,
HiiFormsetLink)) {
- HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate-
FormsetList, HiiFormsetLink);
- HiiFormsetPrivate =
REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
- if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
- HiiFormsetLink = HiiFormsetNextLink;
- continue;
- }
-
- if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
- for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count;
Index++) {
- StringSize += AsciiStrSize (HiiFormsetPrivate-
SupportedSchema.SchemaList[Index]);
- }
- }
-
- HiiFormsetLink = HiiFormsetNextLink;
- }
-
- if (StringSize == 0) {
- return EFI_NOT_FOUND;
- }
-
- StringBuffer = AllocatePool (StringSize);
- if (StringBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- StringIndex = 0;
- HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate-
FormsetList);
- while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList,
HiiFormsetLink)) {
- HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate-
FormsetList, HiiFormsetLink);
- HiiFormsetPrivate =
REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
- if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
- HiiFormsetLink = HiiFormsetNextLink;
- continue;
- }
-
- if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
- for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count;
Index++) {
- AsciiStrCpyS (&StringBuffer[StringIndex], (StringSize - StringIndex),
HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
- StringIndex += AsciiStrLen (HiiFormsetPrivate-
SupportedSchema.SchemaList[Index]);
- StringBuffer[StringIndex] = ';';
- ++StringIndex;
- }
- }
-
- HiiFormsetLink = HiiFormsetNextLink;
- }
-
- StringBuffer[--StringIndex] = '\0';
-
- *SupportedSchema = StringBuffer;
-
- return EFI_SUCCESS;
-}
-
-/**
- Functions which are registered to receive notification of
- database events have this prototype. The actual event is encoded
- in NotifyType. The following table describes how PackageType,
- PackageGuid, Handle, and Package are used for each of the
- notification types.
-
- @param[in] PackageType Package type of the notification.
- @param[in] PackageGuid If PackageType is
- EFI_HII_PACKAGE_TYPE_GUID, then this is
- the pointer to the GUID from the Guid
- field of EFI_HII_PACKAGE_GUID_HEADER.
- Otherwise, it must be NULL.
- @param[in] Package Points to the package referred to by the
- notification Handle The handle of the package
- list which contains the specified package.
- @param[in] Handle The HII handle.
- @param[in] NotifyType The type of change concerning the
- database. See
- EFI_HII_DATABASE_NOTIFY_TYPE.
-
-**/
-EFI_STATUS
-EFIAPI
-RedfishPlatformConfigFormUpdateNotify (
- IN UINT8 PackageType,
- IN CONST EFI_GUID *PackageGuid,
- IN CONST EFI_HII_PACKAGE_HEADER *Package,
- IN EFI_HII_HANDLE Handle,
- IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
- )
-{
- EFI_STATUS Status;
-
- if (NotifyType == EFI_HII_DATABASE_NOTIFY_NEW_PACK || NotifyType
== EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
- //
- // HII formset on this handle is updated by driver during run-time. The
formset needs to be reloaded.
- //
- Status = NotifyFormsetUpdate (Handle, &mRedfishPlatformConfigPrivate-
PendingList);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to notify updated formset of HII
handle: 0x%x\n", __FUNCTION__, Handle));
- return Status;
- }
- } else if (NotifyType == EFI_HII_DATABASE_NOTIFY_REMOVE_PACK) {
- //
- // HII resource is removed. The formset is no longer exist.
- //
- Status = NotifyFormsetDeleted (Handle,
&mRedfishPlatformConfigPrivate->PendingList);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to notify deleted formset of HII
handle: 0x%x\n", __FUNCTION__, Handle));
- return Status;
- }
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- This is a EFI_HII_STRING_PROTOCOL notification event handler.
-
- Install HII package notification.
-
- @param[in] Event Event whose notification function is being invoked.
- @param[in] Context Pointer to the notification function's context.
-
-**/
-VOID
-EFIAPI
-HiiStringProtocolInstalled (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-{
- EFI_STATUS Status;
-
- //
- // Locate HII database protocol.
- //
- Status = gBS->LocateProtocol (
- &gEfiHiiStringProtocolGuid,
- NULL,
- (VOID **)&mRedfishPlatformConfigPrivate->HiiString
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, locate EFI_HII_STRING_PROTOCOL failure:
%r\n", __FUNCTION__, Status));
- return;
- }
-
- gBS->CloseEvent (Event);
- mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent = NULL;
-}
-
-/**
- This is a EFI_HII_DATABASE_PROTOCOL notification event handler.
-
- Install HII package notification.
-
- @param[in] Event Event whose notification function is being invoked.
- @param[in] Context Pointer to the notification function's context.
-
-**/
-VOID
-EFIAPI
-HiiDatabaseProtocolInstalled (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-{
- EFI_STATUS Status;
-
- //
- // Locate HII database protocol.
- //
- Status = gBS->LocateProtocol (
- &gEfiHiiDatabaseProtocolGuid,
- NULL,
- (VOID **)&mRedfishPlatformConfigPrivate->HiiDatabase
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, locate EFI_HII_DATABASE_PROTOCOL
failure: %r\n", __FUNCTION__, Status));
- return;
- }
-
- //
- // Register package notification when new form package is installed.
- //
- Status = mRedfishPlatformConfigPrivate->HiiDatabase-
RegisterPackageNotify (
- mRedfishPlatformConfigPrivate->HiiDatabase,
- EFI_HII_PACKAGE_FORMS,
- NULL,
- RedfishPlatformConfigFormUpdateNotify,
- EFI_HII_DATABASE_NOTIFY_NEW_PACK,
- &mRedfishPlatformConfigPrivate->NotifyHandle
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for
EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__,
Status));
- }
-
- //
- // Register package notification when new form package is updated.
- //
- Status = mRedfishPlatformConfigPrivate->HiiDatabase-
RegisterPackageNotify (
- mRedfishPlatformConfigPrivate->HiiDatabase,
- EFI_HII_PACKAGE_FORMS,
- NULL,
- RedfishPlatformConfigFormUpdateNotify,
- EFI_HII_DATABASE_NOTIFY_ADD_PACK,
- &mRedfishPlatformConfigPrivate->NotifyHandle
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for
EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__,
Status));
- }
-
-#if REDFISH_PLATFORM_CONFIG_DELETE_EXPIRED_FORMSET
- //
- // Register package notification when new form package is removed.
- //
- Status = mRedfishPlatformConfigPrivate->HiiDatabase-
RegisterPackageNotify (
- mRedfishPlatformConfigPrivate->HiiDatabase,
- EFI_HII_PACKAGE_FORMS,
- NULL,
- RedfishPlatformConfigFormUpdateNotify,
- EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
- &mRedfishPlatformConfigPrivate->NotifyHandle
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for
EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__,
Status));
- }
-#endif
-
- gBS->CloseEvent (Event);
- mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent = NULL;
-
-}
-
-/**
- This is a EFI_REGULAR_EXPRESSION_PROTOCOL notification event handler.
-
- @param[in] Event Event whose notification function is being invoked.
- @param[in] Context Pointer to the notification function's context.
-
-**/
-VOID
-EFIAPI
-RegexProtocolInstalled (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-{
- EFI_STATUS Status;
-
- //
- // Locate regular expression protocol.
- //
- Status = gBS->LocateProtocol (
- &gEfiRegularExpressionProtocolGuid,
- NULL,
- (VOID **)&mRedfishPlatformConfigPrivate-
RegularExpressionProtocol
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, locate
EFI_REGULAR_EXPRESSION_PROTOCOL failure: %r\n", __FUNCTION__,
Status));
- return;
- }
-
- gBS->CloseEvent (Event);
- mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent = NULL;
-
-}
-
-/**
- Unloads an image.
-
- @param ImageHandle Handle that identifies the image to be
unloaded.
-
- @retval EFI_SUCCESS The image has been unloaded.
- @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
-
-**/
-EFI_STATUS
-EFIAPI
-RedfishPlatformConfigDxeUnload (
- IN EFI_HANDLE ImageHandle
- )
-{
- EFI_STATUS Status;
-
- if (mRedfishPlatformConfigPrivate != NULL) {
- Status = gBS->UninstallProtocolInterface (
- mRedfishPlatformConfigPrivate->ImageHandle,
- &gEdkIIRedfishPlatformConfigProtocolGuid,
- (VOID*)&mRedfishPlatformConfigPrivate->Protocol
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, can not uninstall
gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
- ASSERT (FALSE);
- }
-
- //
- // Close events
- //
- if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent != NULL) {
- gBS->CloseEvent (mRedfishPlatformConfigPrivate-
HiiDbNotify.ProtocolEvent);
- }
- if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent != NULL)
{
- gBS->CloseEvent (mRedfishPlatformConfigPrivate-
HiiStringNotify.ProtocolEvent);
- }
- if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent != NULL) {
- gBS->CloseEvent (mRedfishPlatformConfigPrivate-
RegexNotify.ProtocolEvent);
- }
-
- //
- // Unregister package notification.
- //
- if (mRedfishPlatformConfigPrivate->NotifyHandle != NULL) {
- mRedfishPlatformConfigPrivate->HiiDatabase->UnregisterPackageNotify
(
- mRedfishPlatformConfigPrivate->HiiDatabase,
- mRedfishPlatformConfigPrivate->NotifyHandle
- );
- }
-
- ReleaseFormsetList (&mRedfishPlatformConfigPrivate->FormsetList);
- FreePool (mRedfishPlatformConfigPrivate);
- mRedfishPlatformConfigPrivate = NULL;
- }
-
- return EFI_SUCCESS;
-}
-
-
-/**
- This is the declaration of an EFI image entry point. This entry point is
- the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
- both device drivers and bus drivers.
-
- @param ImageHandle The firmware allocated handle for the UEFI
image.
- @param SystemTable A pointer to the EFI System Table.
-
- @retval EFI_SUCCESS The operation completed successfully.
- @retval Others An unexpected error occurred.
-**/
-EFI_STATUS
-EFIAPI
-RedfishPlatformConfigDxeEntryPoint (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
-
- mRedfishPlatformConfigPrivate = (REDFISH_PLATFORM_CONFIG_PRIVATE
*)AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PRIVATE));
- if (mRedfishPlatformConfigPrivate == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, can not allocate pool for
REDFISH_PLATFORM_CONFIG_PRIVATE\n", __FUNCTION__));
- ASSERT (FALSE);
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Protocol initialization
- //
- mRedfishPlatformConfigPrivate->ImageHandle = ImageHandle;
- mRedfishPlatformConfigPrivate->Protocol.GetValue =
RedfishPlatformConfigProtocolGetValue;
- mRedfishPlatformConfigPrivate->Protocol.SetValue =
RedfishPlatformConfigProtocolSetValue;
- mRedfishPlatformConfigPrivate->Protocol.GetConfigureLang =
RedfishPlatformConfigProtocolGetConfigureLang;
- mRedfishPlatformConfigPrivate->Protocol.GetSupportedSchema =
RedfishPlatformConfigProtocolGetSupportedSchema;
-
- InitializeListHead (&mRedfishPlatformConfigPrivate->FormsetList);
- InitializeListHead (&mRedfishPlatformConfigPrivate->PendingList);
-
- Status = gBS->InstallProtocolInterface (
- &ImageHandle,
- &gEdkIIRedfishPlatformConfigProtocolGuid,
- EFI_NATIVE_INTERFACE,
- (VOID*)&mRedfishPlatformConfigPrivate->Protocol
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, can not install
gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
- ASSERT (FALSE);
- }
-
- //
- // Install protocol notification if HII database protocol is installed.
- //
- mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent =
EfiCreateProtocolNotifyEvent (
- &gEfiHiiDatabaseProtocolGuid,
- TPL_CALLBACK,
- HiiDatabaseProtocolInstalled,
- NULL,
- &mRedfishPlatformConfigPrivate-
HiiDbNotify.Registration
- );
- if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
gEfiHiiDatabaseProtocolGuid\n", __FUNCTION__));
- ASSERT (FALSE);
- }
-
- //
- // Install protocol notification if HII string protocol is installed.
- //
- mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent =
EfiCreateProtocolNotifyEvent (
- &gEfiHiiStringProtocolGuid,
- TPL_CALLBACK,
- HiiStringProtocolInstalled,
- NULL,
- &mRedfishPlatformConfigPrivate-
HiiStringNotify.Registration
- );
- if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent == NULL)
{
- DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
gEfiHiiStringProtocolGuid\n", __FUNCTION__));
- ASSERT (FALSE);
- }
-
- //
- // Install protocol notification if regular expression protocol is installed.
- //
- mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent =
EfiCreateProtocolNotifyEvent (
- &gEfiRegularExpressionProtocolGuid,
- TPL_CALLBACK,
- RegexProtocolInstalled,
- NULL,
- &mRedfishPlatformConfigPrivate-
RegexNotify.Registration
- );
- if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
gEfiRegularExpressionProtocolGuid\n", __FUNCTION__));
- ASSERT (FALSE);
- }
-
- return EFI_SUCCESS;
-}
+/** @file
+
+ The implementation of EDKII Redfidh Platform Config Protocol.
+
+ (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "RedfishPlatformConfigDxe.h"
+#include "RedfishPlatformConfigImpl.h"
+
+REDFISH_PLATFORM_CONFIG_PRIVATE *mRedfishPlatformConfigPrivate =
NULL;
+
+
+/**
+ Zero extend integer/boolean to UINT64 for comparing.
+
+ @param Value HII Value to be converted.
+
+**/
+UINT64
+ExtendHiiValueToU64 (
+ IN HII_STATEMENT_VALUE *Value
+ )
+{
+ UINT64 Temp;
+
+ Temp = 0;
+ switch (Value->Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ Temp = Value->Value.u8;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ Temp = Value->Value.u16;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ Temp = Value->Value.u32;
+ break;
+
+ case EFI_IFR_TYPE_BOOLEAN:
+ Temp = Value->Value.b;
+ break;
+
+ case EFI_IFR_TYPE_TIME:
+ case EFI_IFR_TYPE_DATE:
+ default:
+ break;
+ }
+
+ return Temp;
+}
+
+/**
+ Set value of a data element in an Array by its Index in ordered list buffer.
+
+ @param Array The data array.
+ @param Type Type of the data in this array.
+ @param Index Zero based index for data in this array.
+ @param Value The value to be set.
+
+**/
+VOID
+OrderedListSetArrayData (
+ IN VOID *Array,
+ IN UINT8 Type,
+ IN UINTN Index,
+ IN UINT64 Value
+ )
+{
+
+ ASSERT (Array != NULL);
+
+ switch (Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ *(((UINT8 *) Array) + Index) = (UINT8) Value;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ *(((UINT16 *) Array) + Index) = (UINT16) Value;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ *(((UINT32 *) Array) + Index) = (UINT32) Value;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ *(((UINT64 *) Array) + Index) = (UINT64) Value;
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ Return data element in an Array by its Index in ordered list array buffer.
+
+ @param Array The data array.
+ @param Type Type of the data in this array.
+ @param Index Zero based index for data in this array.
+
+ @retval Value The data to be returned
+
+**/
+UINT64
+OrderedListGetArrayData (
+ IN VOID *Array,
+ IN UINT8 Type,
+ IN UINTN Index
+ )
+{
+ UINT64 Data;
+
+ ASSERT (Array != NULL);
+
+ Data = 0;
+ switch (Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ Data = (UINT64) *(((UINT8 *) Array) + Index);
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ Data = (UINT64) *(((UINT16 *) Array) + Index);
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ Data = (UINT64) *(((UINT32 *) Array) + Index);
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ Data = (UINT64) *(((UINT64 *) Array) + Index);
+ break;
+
+ default:
+ break;
+ }
+
+ return Data;
+}
+
+/**
+ Find string ID of option if its value equals to given value.
+
+ @param[in] HiiStatement Statement to search.
+ @param[in] Value Target value.
+
+ @retval EFI_SUCCESS HII value is returned successfully.
+ @retval Others Errors occur
+
+**/
+EFI_STRING_ID
+OrderedListOptionValueToStringId (
+ IN HII_STATEMENT *HiiStatement,
+ IN UINT64 Value
+ )
+{
+ LIST_ENTRY *Link;
+ HII_QUESTION_OPTION *Option;
+ BOOLEAN Found;
+ UINT64 CurrentValue;
+
+ if (HiiStatement == NULL) {
+ return 0;
+ }
+
+ if (HiiStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
+ return 0;
+ }
+
+ if (IsListEmpty (&HiiStatement->OptionListHead)) {
+ return 0;
+ }
+
+ Found = FALSE;
+ Link = GetFirstNode (&HiiStatement->OptionListHead);
+ while (!IsNull (&HiiStatement->OptionListHead, Link)) {
+ Option = HII_QUESTION_OPTION_FROM_LINK (Link);
+
+ CurrentValue = ExtendHiiValueToU64 (&Option->Value);
+ if (Value == CurrentValue) {
+ return Option->Text;
+ }
+
+ Link = GetNextNode (&HiiStatement->OptionListHead, Link);
+ }
+
+ return 0;
+}
+
+/**
+ Compare two value in HII statement format.
+
+ @param[in] Value1 Firt value to compare.
+ @param[in] Value2 Second value to be compared.
+
+ @retval INTN 0 is retuned when two values are equal.
+ 1 is returned when first value is greater than second value.
+ -1 is returned when second value is greater than first value.
+
+**/
+INTN
+CompareHiiStatementValue (
+ IN HII_STATEMENT_VALUE *Value1,
+ IN HII_STATEMENT_VALUE *Value2
+ )
+{
+ INTN Result;
+ UINT64 Data1;
+ UINT64 Data2;
+
+ if (Value1 == NULL || Value2 == NULL) {
+ return -1;
+ }
+
+ switch (Value1->Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ Data1 = Value1->Value.u8;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ Data1 = Value1->Value.u16;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ Data1 = Value1->Value.u32;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ Data1 = Value1->Value.u64;
+ break;
+ case EFI_IFR_TYPE_BOOLEAN:
+ Data1 = (Value1->Value.b ? 1 : 0);
+ break;
+ default:
+ return -1;
+ }
+
+ switch (Value2->Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ Data2 = Value2->Value.u8;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ Data2 = Value2->Value.u16;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ Data2 = Value2->Value.u32;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ Data2 = Value2->Value.u64;
+ break;
+ case EFI_IFR_TYPE_BOOLEAN:
+ Data2 = (Value2->Value.b ? 1 : 0);
+ break;
+ default:
+ return -1;
+ }
+
+ Result = (Data1 == Data2 ? 0 : (Data1 > Data2 ? 1 : -1));
+
+ return Result;
+}
+
+/**
+ Convert HII value to the string in HII one-of opcode.
+
+ @param[in] Statement Statement private instance
+
+ @retval EFI_STRING_ID The string ID in HII database.
+ 0 is returned when something goes wrong.
+
+**/
+EFI_STRING_ID
+HiiValueToOneOfOptionStringId (
+ IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement
+ )
+{
+ LIST_ENTRY *Link;
+ HII_QUESTION_OPTION *Option;
+
+ if (Statement->HiiStatement->Operand != EFI_IFR_ONE_OF_OP) {
+ return 0;
+ }
+
+ if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
+ return 0;
+ }
+
+ Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
+ while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
+ Option = HII_QUESTION_OPTION_FROM_LINK (Link);
+
+ if (CompareHiiStatementValue (&Statement->HiiStatement->Value,
&Option->Value) == 0) {
+ return Option->Text;
+ }
+
+ Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
+ }
+
+ return 0;
+}
+
+/**
+ Convert HII string to the value in HII one-of opcode.
+
+ @param[in] Statement Statement private instance
+ @param[in] Schema Schema string
+ @param[in] HiiString Input string
+ @param[out] Value Value returned
+
+ @retval EFI_SUCCESS HII value is returned successfully.
+ @retval Others Errors occur
+
+**/
+EFI_STATUS
+HiiStringToOneOfOptionValue (
+ IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement,
+ IN CHAR8 *Schema,
+ IN EFI_STRING HiiString,
+ OUT HII_STATEMENT_VALUE *Value
+ )
+{
+ LIST_ENTRY *Link;
+ HII_QUESTION_OPTION *Option;
+ EFI_STRING TmpString;
+ BOOLEAN Found;
+
+ if (Statement == NULL || IS_EMPTY_STRING (HiiString) || Value == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Statement->HiiStatement->Operand != EFI_IFR_ONE_OF_OP) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
+ return EFI_NOT_FOUND;
+ }
+
+ Found = FALSE;
+ Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
+ while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
+ Option = HII_QUESTION_OPTION_FROM_LINK (Link);
+
+ TmpString = HiiGetRedfishString (Statement->ParentForm-
ParentFormset->HiiHandle, Schema, Option->Text);
+ if (TmpString != NULL) {
+ if (StrCmp (TmpString, HiiString) == 0) {
+ CopyMem (Value, &Option->Value, sizeof (HII_STATEMENT_VALUE));
+ Found = TRUE;
+ }
+ FreePool (TmpString);
+ }
+
+ if (Found) {
+ return EFI_SUCCESS;
+ }
+
+ Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Convert HII value to numeric value in Redfish format.
+
+ @param[in] Value Value to be converted.
+ @param[out] RedfishValue Value in Redfish format.
+
+ @retval EFI_SUCCESS Redfish value is returned successfully.
+ @retval Others Errors occur
+
+**/
+EFI_STATUS
+HiiValueToRedfishNumeric (
+ IN HII_STATEMENT_VALUE *Value,
+ OUT EDKII_REDFISH_VALUE *RedfishValue
+ )
+{
+ if (Value == NULL || RedfishValue == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ switch (Value->Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
+ RedfishValue->Value.Integer = (INT64)Value->Value.u8;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
+ RedfishValue->Value.Integer = (INT64)Value->Value.u16;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
+ RedfishValue->Value.Integer = (INT64)Value->Value.u32;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
+ RedfishValue->Value.Integer = (INT64)Value->Value.u64;
+ break;
+ case EFI_IFR_TYPE_BOOLEAN:
+ RedfishValue->Type = REDFISH_VALUE_TYPE_BOOLEAN;
+ RedfishValue->Value.Boolean = Value->Value.b;
+ break;
+ default:
+ RedfishValue->Type = REDFISH_VALUE_TYPE_UNKNOWN;
+ break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Convert numeric value in Redfish format to HII value.
+
+ @param[in] RedfishValue Value in Redfish format to be converted.
+ @param[out] Value HII value returned.
+
+ @retval EFI_SUCCESS HII value is returned successfully.
+ @retval Others Errors occur
+
+**/
+EFI_STATUS
+RedfishNumericToHiiValue (
+ IN EDKII_REDFISH_VALUE *RedfishValue,
+ OUT HII_STATEMENT_VALUE *Value
+ )
+{
+ if (Value == NULL || RedfishValue == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ switch (RedfishValue->Type) {
+ case REDFISH_VALUE_TYPE_INTEGER:
+ Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
+ Value->Value.u64 = (UINT64)RedfishValue->Value.Integer;
+ break;
+ case REDFISH_VALUE_TYPE_BOOLEAN:
+ Value->Type = EFI_IFR_TYPE_BOOLEAN;
+ Value->Value.b = RedfishValue->Value.Boolean;
+ break;
+ default:
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+ break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Dump the value in ordered list buffer.
+
+ @param[in] OrderedListStatement Ordered list statement.
+
+**/
+VOID
+DumpOrderedListValue (
+ IN HII_STATEMENT *OrderedListStatement
+ )
+{
+ UINT8 *Value8;
+ UINT16 *Value16;
+ UINT32 *Value32;
+ UINT64 *Value64;
+ UINTN Count;
+ UINTN Index;
+
+ if (OrderedListStatement == NULL || OrderedListStatement->Operand !=
EFI_IFR_ORDERED_LIST_OP) {
+ return;
+ }
+
+ DEBUG ((DEBUG_ERROR, "Value.Type= 0x%x\n", OrderedListStatement-
Value.Type));
+ DEBUG ((DEBUG_ERROR, "Value.BufferValueType= 0x%x\n",
OrderedListStatement->Value.BufferValueType));
+ DEBUG ((DEBUG_ERROR, "Value.BufferLen= 0x%x\n",
OrderedListStatement->Value.BufferLen));
+ DEBUG ((DEBUG_ERROR, "Value.Buffer= 0x%x\n", OrderedListStatement-
Value.Buffer));
+ DEBUG ((DEBUG_ERROR, "Value.MaxContainers= 0x%x\n",
OrderedListStatement->ExtraData.OrderListData.MaxContainers));
+ DEBUG ((DEBUG_ERROR, "StorageWidth= 0x%x\n",
OrderedListStatement->StorageWidth));
+
+ if (OrderedListStatement->Value.Buffer == NULL) {
+ return;
+ }
+
+ Value8 = NULL;
+ Value16 = NULL;
+ Value32 = NULL;
+ Value64 = NULL;
+ Count = 0;
+
+ switch (OrderedListStatement->Value.BufferValueType) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ Value8 = (UINT8 *)OrderedListStatement->Value.Buffer;
+ Count = OrderedListStatement->StorageWidth / sizeof (UINT8);
+ for (Index = 0; Index < Count; Index++) {
+ DEBUG ((DEBUG_ERROR, "%d ", Value8[Index]));
+ }
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ Value16 = (UINT16 *)OrderedListStatement->Value.Buffer;
+ Count = OrderedListStatement->StorageWidth / sizeof (UINT16);
+ for (Index = 0; Index < Count; Index++) {
+ DEBUG ((DEBUG_ERROR, "%d ", Value16[Index]));
+ }
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ Value32 = (UINT32 *)OrderedListStatement->Value.Buffer;
+ Count = OrderedListStatement->StorageWidth / sizeof (UINT32);
+ for (Index = 0; Index < Count; Index++) {
+ DEBUG ((DEBUG_ERROR, "%d ", Value32[Index]));
+ }
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ Value64 = (UINT64 *)OrderedListStatement->Value.Buffer;
+ Count = OrderedListStatement->StorageWidth / sizeof (UINT64);
+ for (Index = 0; Index < Count; Index++) {
+ DEBUG ((DEBUG_ERROR, "%d ", Value64[Index]));
+ }
+ break;
+ default:
+ Value8 = (UINT8 *)OrderedListStatement->Value.Buffer;
+ Count = OrderedListStatement->StorageWidth / sizeof (UINT8);
+ for (Index = 0; Index < Count; Index++) {
+ DEBUG ((DEBUG_ERROR, "%d ", Value8[Index]));
+ }
+ break;
+ }
+
+ DEBUG ((DEBUG_ERROR, "\n"));
+}
+
+/**
+ Convert HII value to the string in HII ordered list opcode. It's caller's
+ responsibility to free returned buffer using FreePool().
+
+ @param[in] Statement Statement private instance
+ @param[out] ReturnSize The size of returned array
+
+ @retval EFI_STRING_ID The string ID array for options in ordered list.
+
+**/
+EFI_STRING_ID *
+HiiValueToOrderedListOptionStringId (
+ IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement,
+ OUT UINTN *ReturnSize
+ )
+{
+ LIST_ENTRY *Link;
+ HII_QUESTION_OPTION *Option;
+ UINTN OptionCount;
+ EFI_STRING_ID *ReturnedArray;
+ UINTN Index;
+ UINT64 Value;
+
+ if (Statement == NULL || ReturnSize == NULL) {
+ return NULL;
+ }
+
+ *ReturnSize = 0;
+
+ if (Statement->HiiStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
+ return NULL;
+ }
+
+ if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
+ return NULL;
+ }
+
+ DEBUG_CODE (
+ DumpOrderedListValue (Statement->HiiStatement);
+ );
+
+ OptionCount = 0;
+ Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
+ while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
+ Option = HII_QUESTION_OPTION_FROM_LINK (Link);
+
+ ++OptionCount;
+
+ Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
+ }
+
+ *ReturnSize = OptionCount;
+ ReturnedArray = AllocatePool (sizeof (EFI_STRING_ID) * OptionCount);
+ if (ReturnedArray == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__));
+ *ReturnSize = 0;
+ return NULL;
+ }
+
+ for (Index = 0; Index < OptionCount; Index++) {
+ Value = OrderedListGetArrayData (Statement->HiiStatement-
Value.Buffer, Statement->HiiStatement->Value.BufferValueType, Index);
+ ReturnedArray[Index] = OrderedListOptionValueToStringId (Statement-
HiiStatement, Value);
+ }
+
+ return ReturnedArray;
+}
+
+/**
+ Convert HII string to the value in HII ordered list opcode.
+
+ @param[in] Statement Statement private instance
+ @param[in] Schema Schema string
+ @param[in] HiiString Input string
+ @param[out] Value Value returned
+
+ @retval EFI_SUCCESS HII value is returned successfully.
+ @retval Others Errors occur
+
+**/
+EFI_STATUS
+HiiStringToOrderedListOptionValue (
+ IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement,
+ IN CHAR8 *Schema,
+ IN EFI_STRING HiiString,
+ OUT UINT64 *Value
+ )
+{
+ LIST_ENTRY *Link;
+ HII_QUESTION_OPTION *Option;
+ EFI_STRING TmpString;
+ BOOLEAN Found;
+
+ if (Statement == NULL || IS_EMPTY_STRING (HiiString) || Value == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Value = 0;
+
+ if (Statement->HiiStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
+ return EFI_NOT_FOUND;
+ }
+
+ Found = FALSE;
+ Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
+ while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
+ Option = HII_QUESTION_OPTION_FROM_LINK (Link);
+
+ TmpString = HiiGetRedfishString (Statement->ParentForm-
ParentFormset->HiiHandle, Schema, Option->Text);
+ if (TmpString != NULL) {
+ if (StrCmp (TmpString, HiiString) == 0) {
+ *Value = ExtendHiiValueToU64 (&Option->Value);
+ Found = TRUE;
+ }
+ FreePool (TmpString);
+ }
+
+ if (Found) {
+ return EFI_SUCCESS;
+ }
+
+ Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Convert input ascii string to unicode string. It's caller's
+ responsibility to free returned buffer using FreePool().
+
+ @param[in] AsciiString Ascii string to be converted.
+
+ @retval CHAR16 * Unicode string on return.
+
+**/
+EFI_STRING
+StrToUnicodeStr (
+ IN CHAR8 *AsciiString
+ )
+{
+ UINTN StringLen;
+ EFI_STRING Buffer;
+ EFI_STATUS Status;
+
+ if (AsciiString == NULL || AsciiString[0] == '\0') {
+ return NULL;
+ }
+
+ StringLen = AsciiStrLen (AsciiString) + 1;
+ Buffer = AllocatePool (StringLen * sizeof (CHAR16));
+ if (Buffer == NULL) {
+ return NULL;
+ }
+
+ Status = AsciiStrToUnicodeStrS (AsciiString, Buffer, StringLen);
+ if (EFI_ERROR (Status)) {
+ FreePool (Buffer);
+ return NULL;
+ }
+
+ return Buffer;
+}
+
+/**
+ Return the full Redfish schema string from the given Schema and Version.
+
+ Returned schema string is: Schema + '.' + Version
+
+ @param[in] Schema Schema string
+ @param[in] Version Schema version string
+
+ @retval CHAR8 * Schema string. NULL when errors occur.
+
+**/
+CHAR8 *
+GetFullSchemaString (
+ IN CHAR8 *Schema,
+ IN CHAR8 *Version
+ )
+{
+ UINTN Size;
+ CHAR8 *FullName;
+
+ if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version)) {
+ return NULL;
+ }
+
+ Size = AsciiStrSize(CONFIGURE_LANGUAGE_PREFIX) + AsciiStrSize
(Schema) + AsciiStrSize (Version);
+
+ FullName = AllocatePool (Size);
+ if (FullName == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, out-of-resource\n", __FUNCTION__));
+ return NULL;
+ }
+
+ AsciiSPrint (FullName, Size, "%a%a.%a", CONFIGURE_LANGUAGE_PREFIX,
Schema, Version);
+
+ return FullName;
+}
+
+/**
+ Common implementation to get statement private instance.
+
+ @param[in] RedfishPlatformConfigPrivate Private instance.
+ @param[in] Schema Redfish schema string.
+ @param[in] ConfigureLang Configure language that refers to this
statement.
+ @param[out] Statement Statement instance
+
+ @retval EFI_SUCCESS HII value is returned successfully.
+ @retval Others Errors occur
+
+**/
+EFI_STATUS
+RedfishPlatformConfigGetStatementCommon (
+ IN REDFISH_PLATFORM_CONFIG_PRIVATE
*RedfishPlatformConfigPrivate,
+ IN CHAR8 *Schema,
+ IN EFI_STRING ConfigureLang,
+ OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE **Statement
+ )
+{
+ EFI_STATUS Status;
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
+
+ if (RedfishPlatformConfigPrivate == NULL || IS_EMPTY_STRING (Schema)
|| IS_EMPTY_STRING (ConfigureLang) || Statement == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Statement = NULL;
+
+ Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
&RedfishPlatformConfigPrivate->PendingList);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
__FUNCTION__, Status));
+ return Status;
+ }
+
+ TargetStatement = GetStatementPrivateByConfigureLang
(&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
+ if (TargetStatement == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, No match HII statement is found by the
given %s in schema %a\n", __FUNCTION__, ConfigureLang, Schema));
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Find current HII question value.
+ //
+ Status = GetQuestionValue (
+ TargetStatement->ParentForm->ParentFormset->HiiFormSet,
+ TargetStatement->ParentForm->HiiForm,
+ TargetStatement->HiiStatement,
+ GetSetValueWithHiiDriver
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to get question current value: %r\n",
__FUNCTION__, Status));
+ return Status;
+ }
+
+
+ if (TargetStatement->HiiStatement->Value.Type ==
EFI_IFR_TYPE_UNDEFINED) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Return Value.
+ //
+ *Statement = TargetStatement;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Get Redfish value with the given Schema and Configure Language.
+
+ @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+ @param[in] Schema The Redfish schema to query.
+ @param[in] Version The Redfish version to query.
+ @param[in] ConfigureLang The target value which match this configure
Language.
+ @param[out] Value The returned value.
+
+ @retval EFI_SUCCESS Value is returned successfully.
+ @retval Others Some error happened.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformConfigProtocolGetValue (
+ IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+ IN CHAR8 *Schema,
+ IN CHAR8 *Version,
+ IN EFI_STRING ConfigureLang,
+ OUT EDKII_REDFISH_VALUE *Value
+ )
+{
+ EFI_STATUS Status;
+ REDFISH_PLATFORM_CONFIG_PRIVATE
*RedfishPlatformConfigPrivate;
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
+ EFI_STRING_ID StringId;
+ EFI_STRING_ID *StringIdArray;
+ CHAR8 *FullSchema;
+ EFI_STRING HiiString;
+ UINTN Count;
+ UINTN Index;
+
+ if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
(Version) || IS_EMPTY_STRING (ConfigureLang) || Value == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ RedfishPlatformConfigPrivate =
REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
+ Value->Type = REDFISH_VALUE_TYPE_UNKNOWN;
+ Value->ArrayCount = 0;
+ Count = 0;
+ FullSchema = NULL;
+ HiiString = NULL;
+ StringIdArray = NULL;
+
+ FullSchema = GetFullSchemaString (Schema, Version);
+ if (FullSchema == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = RedfishPlatformConfigGetStatementCommon
(RedfishPlatformConfigPrivate, FullSchema, ConfigureLang,
&TargetStatement);
+ if (EFI_ERROR (Status)) {
+ goto RELEASE_RESOURCE;
+ }
+
+ switch (TargetStatement->HiiStatement->Operand) {
+ case EFI_IFR_ONE_OF_OP:
+ StringId = HiiValueToOneOfOptionStringId (TargetStatement);
+ if (StringId == 0) {
+ ASSERT (FALSE);
+ Status = EFI_DEVICE_ERROR;
+ goto RELEASE_RESOURCE;
+ }
+
+ Value->Value.Buffer = HiiGetRedfishAsciiString (TargetStatement-
ParentForm->ParentFormset->HiiHandle, FullSchema, StringId);
+ if (Value->Value.Buffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto RELEASE_RESOURCE;
+ }
+
+ Value->Type = REDFISH_VALUE_TYPE_STRING;
+ break;
+ case EFI_IFR_STRING_OP:
+ if (TargetStatement->HiiStatement->Value.Type !=
EFI_IFR_TYPE_STRING) {
+ ASSERT (FALSE);
+ Status = EFI_DEVICE_ERROR;
+ goto RELEASE_RESOURCE;
+ }
+
+ Value->Type = REDFISH_VALUE_TYPE_STRING;
+ Value->Value.Buffer = AllocatePool (StrLen ((CHAR16
*)TargetStatement->HiiStatement->Value.Buffer) + 1);
+ UnicodeStrToAsciiStrS ((CHAR16 *)TargetStatement->HiiStatement-
Value.Buffer, Value->Value.Buffer, StrLen ((CHAR16 *)TargetStatement-
HiiStatement->Value.Buffer) + 1);
+ break;
+ case EFI_IFR_CHECKBOX_OP:
+ case EFI_IFR_NUMERIC_OP:
+ Status = HiiValueToRedfishNumeric (&TargetStatement->HiiStatement-
Value, Value);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to convert HII value to Redfish
value: %r\n", __FUNCTION__, Status));
+ goto RELEASE_RESOURCE;
+ }
+ break;
+ case EFI_IFR_ACTION_OP:
+ if (TargetStatement->HiiStatement->Value.Type !=
EFI_IFR_TYPE_ACTION) {
+ ASSERT (FALSE);
+ Status = EFI_DEVICE_ERROR;
+ goto RELEASE_RESOURCE;
+ }
+
+ //
+ // Action has no value. Just return unknown type.
+ //
+ Value->Type = REDFISH_VALUE_TYPE_UNKNOWN;
+ break;
+ case EFI_IFR_ORDERED_LIST_OP:
+ StringIdArray = HiiValueToOrderedListOptionStringId (TargetStatement,
&Count);
+ if (StringIdArray == NULL) {
+ ASSERT (FALSE);
+ Status = EFI_DEVICE_ERROR;
+ goto RELEASE_RESOURCE;
+ }
+
+ Value->Value.StringArray = AllocatePool (sizeof (CHAR8 *) * Count);
+ if (Value->Value.StringArray == NULL) {
+ ASSERT (FALSE);
+ Status = EFI_OUT_OF_RESOURCES;
+ goto RELEASE_RESOURCE;
+ }
+
+ for (Index = 0; Index < Count; Index++) {
+ ASSERT (StringIdArray[Index] != 0);
+ Value->Value.StringArray[Index] = HiiGetRedfishAsciiString
(TargetStatement->ParentForm->ParentFormset->HiiHandle, FullSchema,
StringIdArray[Index]);
+ }
+
+ Value->ArrayCount = Count;
+ Value->Type = REDFISH_VALUE_TYPE_STRING_ARRAY;
+ break;
+ default:
+ DEBUG ((DEBUG_ERROR, "%a, catch unsupported type: 0x%x! Please
contact with author if we need to support this type.\n", __FUNCTION__,
TargetStatement->HiiStatement->Operand));
+ ASSERT (FALSE);
+ Status = EFI_UNSUPPORTED;
+ goto RELEASE_RESOURCE;
+ }
+
+RELEASE_RESOURCE:
+
+ if (FullSchema != NULL) {
+ FreePool (FullSchema);
+ }
+
+ if (HiiString != NULL) {
+ FreePool (HiiString);
+ }
+
+ if (StringIdArray != NULL) {
+ FreePool (StringIdArray);
+ }
+
+ return Status;
+}
+
+/**
+ Function to save question value into HII database.
+
+ @param[in] HiiFormset HII form-set instance
+ @param[in] HiiForm HII form instance
+ @param[in] HiiStatement HII statement that keeps new value.
+ @param[in] Value New value to applyu.
+
+ @retval EFI_SUCCESS HII value is returned successfully.
+ @retval Others Errors occur
+
+**/
+EFI_STATUS
+RedfishPlatformConfigSaveQuestionValue (
+ IN HII_FORMSET *HiiFormset,
+ IN HII_FORM *HiiForm,
+ IN HII_STATEMENT *HiiStatement,
+ IN HII_STATEMENT_VALUE *Value
+ )
+{
+ EFI_STATUS Status;
+
+ if (HiiFormset == NULL || HiiForm == NULL || HiiStatement == NULL ||
Value == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = SetQuestionValue (
+ HiiFormset,
+ HiiForm,
+ HiiStatement,
+ Value
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to set question value: %r\n",
__FUNCTION__, Status));
+ return Status;
+ }
+
+ Status = SubmitForm (HiiFormset, HiiForm);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to submit form: %r\n",
__FUNCTION__, Status));
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Common implementation to set statement private instance.
+
+ @param[in] RedfishPlatformConfigPrivate Private instance.
+ @param[in] Schema Redfish schema string.
+ @param[in] ConfigureLang Configure language that refers to this
statement.
+ @param[in] Statement Statement instance
+
+ @retval EFI_SUCCESS HII value is returned successfully.
+ @retval Others Errors occur
+
+**/
+EFI_STATUS
+RedfishPlatformConfigSetStatementCommon (
+ IN REDFISH_PLATFORM_CONFIG_PRIVATE
*RedfishPlatformConfigPrivate,
+ IN CHAR8 *Schema,
+ IN EFI_STRING ConfigureLang,
+ IN HII_STATEMENT_VALUE *StatementValue
+ )
+{
+ EFI_STATUS Status;
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
+ EFI_STRING TempBuffer;
+ UINT8 *StringArray;
+ UINTN Index;
+ UINT64 Value;
+ CHAR8 **CharArray;
+
+ if (RedfishPlatformConfigPrivate == NULL || IS_EMPTY_STRING (Schema)
|| IS_EMPTY_STRING (ConfigureLang) || StatementValue == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TempBuffer = NULL;
+ StringArray = NULL;
+
+ Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
&RedfishPlatformConfigPrivate->PendingList);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
__FUNCTION__, Status));
+ return Status;
+ }
+
+ TargetStatement = GetStatementPrivateByConfigureLang
(&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
+ if (TargetStatement == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, No match HII statement is found by the
given %s in schema %a\n", __FUNCTION__, ConfigureLang, Schema));
+ return EFI_NOT_FOUND;
+ }
+
+ if (StatementValue->Type != TargetStatement->HiiStatement-
Value.Type) {
+ //
+ // We treat one-of type as string in Redfish. But one-of statement is not
+ // in string format from HII point of view. Do a patch here.
+ //
+ if (TargetStatement->HiiStatement->Operand == EFI_IFR_ONE_OF_OP
&& StatementValue->Type == EFI_IFR_TYPE_STRING) {
+
+ TempBuffer = StrToUnicodeStr ((CHAR8 *)StatementValue->Buffer);
+ if (TempBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ FreePool (StatementValue->Buffer);
+ StatementValue->Buffer = NULL;
+ StatementValue->BufferLen = 0;
+
+ Status = HiiStringToOneOfOptionValue (TargetStatement, Schema,
TempBuffer, StatementValue);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to find option value by the given
%s\n", __FUNCTION__, TempBuffer));
+ FreePool (TempBuffer);
+ return EFI_NOT_FOUND;
+ }
+
+ FreePool (TempBuffer);
+ } else if (TargetStatement->HiiStatement->Operand ==
EFI_IFR_ORDERED_LIST_OP && StatementValue->Type ==
EFI_IFR_TYPE_STRING) {
+ //
+ // We treat ordered list type as string in Redfish. But ordered list
statement is not
+ // in string format from HII point of view. Do a patch here.
+ //
+ StringArray = AllocateZeroPool (TargetStatement->HiiStatement-
StorageWidth);
+ if (StringArray == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Arrage new option order from input string array
+ //
+ CharArray = (CHAR8 **)StatementValue->Buffer;
+ for (Index = 0; Index < StatementValue->BufferLen; Index++) {
+ TempBuffer = StrToUnicodeStr (CharArray[Index]);
+ if (TempBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = HiiStringToOrderedListOptionValue (TargetStatement, Schema,
TempBuffer, &Value);
+ if (EFI_ERROR (Status)) {
+ ASSERT (FALSE);
+ continue;
+ }
+ FreePool (TempBuffer);
+ OrderedListSetArrayData (StringArray, TargetStatement->HiiStatement-
Value.BufferValueType, Index, Value);
+ }
+
+ StatementValue->Type = EFI_IFR_TYPE_BUFFER;
+ StatementValue->Buffer = StringArray;
+ StatementValue->BufferLen = TargetStatement->HiiStatement-
StorageWidth;
+ StatementValue->BufferValueType = TargetStatement->HiiStatement-
Value.BufferValueType;
+ } else if (TargetStatement->HiiStatement->Operand ==
EFI_IFR_NUMERIC_OP && StatementValue->Type ==
EFI_IFR_TYPE_NUM_SIZE_64) {
+ //
+ // Redfish only has numeric value type and it does not care about the
value size.
+ // Do a patch here so we have proper value size applied.
+ //
+ StatementValue->Type = TargetStatement->HiiStatement->Value.Type;
+ } else {
+ DEBUG ((DEBUG_ERROR, "%a, catch value type mismatch! input type:
0x%x but target value type: 0x%x\n", __FUNCTION__, StatementValue-
Type, TargetStatement->HiiStatement->Value.Type));
+ ASSERT (FALSE);
+ }
+ }
+
+ Status = RedfishPlatformConfigSaveQuestionValue (
+ TargetStatement->ParentForm->ParentFormset->HiiFormSet,
+ TargetStatement->ParentForm->HiiForm,
+ TargetStatement->HiiStatement,
+ StatementValue
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to save question value: %r\n",
__FUNCTION__, Status));
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Set Redfish value with the given Schema and Configure Language.
+
+ @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+ @param[in] Schema The Redfish schema to query.
+ @param[in] Version The Redfish version to query.
+ @param[in] ConfigureLang The target value which match this configure
Language.
+ @param[in] Value The value to set.
+
+ @retval EFI_SUCCESS Value is returned successfully.
+ @retval Others Some error happened.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformConfigProtocolSetValue (
+ IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+ IN CHAR8 *Schema,
+ IN CHAR8 *Version,
+ IN EFI_STRING ConfigureLang,
+ IN EDKII_REDFISH_VALUE Value
+ )
+{
+ EFI_STATUS Status;
+ REDFISH_PLATFORM_CONFIG_PRIVATE
*RedfishPlatformConfigPrivate;
+ CHAR8 *FullSchema;
+ HII_STATEMENT_VALUE NewValue;
+
+ if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
(Version) || IS_EMPTY_STRING (ConfigureLang)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Value.Type == REDFISH_VALUE_TYPE_UNKNOWN || Value.Type >=
REDFISH_VALUE_TYPE_MAX) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ RedfishPlatformConfigPrivate =
REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
+ FullSchema = NULL;
+
+ FullSchema = GetFullSchemaString (Schema, Version);
+ if (FullSchema == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ZeroMem (&NewValue, sizeof (HII_STATEMENT_VALUE));
+
+ switch (Value.Type) {
+ case REDFISH_VALUE_TYPE_INTEGER:
+ case REDFISH_VALUE_TYPE_BOOLEAN:
+ Status = RedfishNumericToHiiValue (&Value, &NewValue);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to convert Redfish value to Hii
value: %r\n", __FUNCTION__, Status));
+ goto RELEASE_RESOURCE;
+ }
+ break;
+ case REDFISH_VALUE_TYPE_STRING:
+ NewValue.Type = EFI_IFR_TYPE_STRING;
+ NewValue.BufferLen = (UINT16)AsciiStrSize (Value.Value.Buffer);
+ NewValue.Buffer = AllocateCopyPool (NewValue.BufferLen,
Value.Value.Buffer);
+ if (NewValue.Buffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto RELEASE_RESOURCE;
+ }
+ break;
+ case REDFISH_VALUE_TYPE_STRING_ARRAY:
+ NewValue.Type = EFI_IFR_TYPE_STRING;
+ NewValue.BufferLen = (UINT16)Value.ArrayCount;
+ NewValue.Buffer = (UINT8 *)Value.Value.StringArray;
+ break;
+ default:
+ ASSERT (FALSE);
+ break;
+ }
+
+ Status = RedfishPlatformConfigSetStatementCommon
(RedfishPlatformConfigPrivate, FullSchema, ConfigureLang, &NewValue);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to set value to statement: %r\n",
__FUNCTION__, Status));
+ }
+
+RELEASE_RESOURCE:
+
+ if (FullSchema != NULL) {
+ FreePool (FullSchema);
+ }
+
+ return Status;
+}
+
+/**
+ Get the list of Configure Language from platform configuration by the
given Schema and RegexPattern.
+
+ @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+ @param[in] Schema The Redfish schema to query.
+ @param[in] Version The Redfish version to query.
+ @param[in] RegexPattern The target Configure Language pattern.
This is used for regular expression matching.
+ @param[out] ConfigureLangList The list of Configure Language.
+ @param[out] Count The number of Configure Language in
ConfigureLangList.
+
+ @retval EFI_SUCCESS ConfigureLangList is returned successfully.
+ @retval Others Some error happened.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformConfigProtocolGetConfigureLang (
+ IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+ IN CHAR8 *Schema,
+ IN CHAR8 *Version,
+ IN EFI_STRING RegexPattern,
+ OUT EFI_STRING **ConfigureLangList,
+ OUT UINTN *Count
+ )
+{
+ REDFISH_PLATFORM_CONFIG_PRIVATE
*RedfishPlatformConfigPrivate;
+ EFI_STATUS Status;
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST StatementList;
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF
*StatementRef;
+ LIST_ENTRY *NextLink;
+ EFI_STRING TmpString;
+ EFI_STRING *TmpConfigureLangList;
+ UINTN Index;
+ CHAR8 *FullSchema;
+
+ if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
(Version) || Count == NULL || ConfigureLangList == NULL ||
IS_EMPTY_STRING (RegexPattern)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Count = 0;
+ *ConfigureLangList = NULL;
+ FullSchema = NULL;
+ RedfishPlatformConfigPrivate =
REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
+
+ Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
&RedfishPlatformConfigPrivate->PendingList);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
__FUNCTION__, Status));
+ return Status;
+ }
+
+ FullSchema = GetFullSchemaString (Schema, Version);
+ if (FullSchema == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = GetStatementPrivateByConfigureLangRegex (
+ RedfishPlatformConfigPrivate->RegularExpressionProtocol,
+ &RedfishPlatformConfigPrivate->FormsetList,
+ FullSchema,
+ RegexPattern,
+ &StatementList
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a,
GetStatementPrivateByConfigureLangRegex failure: %r\n", __FUNCTION__,
Status));
+ goto RELEASE_RESOURCE;
+ }
+
+ if (!IsListEmpty (&StatementList.StatementList)) {
+
+ TmpConfigureLangList = AllocateZeroPool (sizeof (CHAR16 *) *
StatementList.Count);
+ if (TmpConfigureLangList == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto RELEASE_RESOURCE;
+ }
+
+ Index = 0;
+ NextLink = GetFirstNode (&StatementList.StatementList);
+ while (!IsNull (&StatementList.StatementList, NextLink)) {
+ StatementRef =
REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
+ NextLink = GetNextNode (&StatementList.StatementList, NextLink);
+
+ ASSERT (StatementRef->Statement->Description != 0);
+ if (StatementRef->Statement->Description != 0) {
+ TmpString = HiiGetRedfishString (StatementRef->Statement-
ParentForm->ParentFormset->HiiHandle, FullSchema, StatementRef-
Statement->Description);
+ ASSERT (TmpString != NULL);
+ if (TmpString != NULL) {
+ TmpConfigureLangList[Index] = AllocateCopyPool (StrSize (TmpString),
TmpString);
+ ASSERT (TmpConfigureLangList[Index] != NULL);
+ FreePool (TmpString);
+ ++Index;
+ }
+ }
+ }
+ }
+
+ *Count = StatementList.Count;
+ *ConfigureLangList = TmpConfigureLangList;
+
+RELEASE_RESOURCE:
+
+ if (FullSchema != NULL) {
+ FreePool (FullSchema);
+ }
+
+ ReleaseStatementList (&StatementList);
+
+ return Status;
+}
+
+/**
+ Get the list of supported Redfish schema from paltform configuration on
give HII handle.
+
+ @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+ @param[in] HiiHandle The target handle to search. If handle is NULL,
+ this function return all schema from HII database.
+ @param[out] SupportedSchema The supported schema list which is
separated by ';'.
+ The SupportedSchema is allocated by the callee. It's
caller's
+ responsibility to free this buffer using FreePool().
+
+ @retval EFI_SUCCESS Schema is returned successfully.
+ @retval Others Some error happened.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformConfigProtocolGetSupportedSchema (
+ IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+ IN EFI_HII_HANDLE HiiHandle, OPTIONAL
+ OUT CHAR8 **SupportedSchema
+ )
+{
+ REDFISH_PLATFORM_CONFIG_PRIVATE
*RedfishPlatformConfigPrivate;
+ EFI_STATUS Status;
+ LIST_ENTRY *HiiFormsetLink;
+ LIST_ENTRY *HiiFormsetNextLink;
+ REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
+ UINTN Index;
+ UINTN StringSize;
+ CHAR8 *StringBuffer;
+ UINTN StringIndex;
+
+ if (This == NULL || SupportedSchema == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *SupportedSchema = NULL;
+
+ RedfishPlatformConfigPrivate =
REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
+
+ Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
&RedfishPlatformConfigPrivate->PendingList);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
__FUNCTION__, Status));
+ return Status;
+ }
+
+ if (IsListEmpty (&RedfishPlatformConfigPrivate->FormsetList)) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Calculate for string buffer size.
+ //
+ StringSize = 0;
+ HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate-
FormsetList);
+ while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList,
HiiFormsetLink)) {
+ HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate-
FormsetList, HiiFormsetLink);
+ HiiFormsetPrivate =
REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+ if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
+ HiiFormsetLink = HiiFormsetNextLink;
+ continue;
+ }
+
+ if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
+ for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count;
Index++) {
+ StringSize += AsciiStrSize (HiiFormsetPrivate-
SupportedSchema.SchemaList[Index]);
+ }
+ }
+
+ HiiFormsetLink = HiiFormsetNextLink;
+ }
+
+ if (StringSize == 0) {
+ return EFI_NOT_FOUND;
+ }
+
+ StringBuffer = AllocatePool (StringSize);
+ if (StringBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ StringIndex = 0;
+ HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate-
FormsetList);
+ while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList,
HiiFormsetLink)) {
+ HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate-
FormsetList, HiiFormsetLink);
+ HiiFormsetPrivate =
REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+ if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
+ HiiFormsetLink = HiiFormsetNextLink;
+ continue;
+ }
+
+ if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
+ for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count;
Index++) {
+ AsciiStrCpyS (&StringBuffer[StringIndex], (StringSize - StringIndex),
HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
+ StringIndex += AsciiStrLen (HiiFormsetPrivate-
SupportedSchema.SchemaList[Index]);
+ StringBuffer[StringIndex] = ';';
+ ++StringIndex;
+ }
+ }
+
+ HiiFormsetLink = HiiFormsetNextLink;
+ }
+
+ StringBuffer[--StringIndex] = '\0';
+
+ *SupportedSchema = StringBuffer;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Functions which are registered to receive notification of
+ database events have this prototype. The actual event is encoded
+ in NotifyType. The following table describes how PackageType,
+ PackageGuid, Handle, and Package are used for each of the
+ notification types.
+
+ @param[in] PackageType Package type of the notification.
+ @param[in] PackageGuid If PackageType is
+ EFI_HII_PACKAGE_TYPE_GUID, then this is
+ the pointer to the GUID from the Guid
+ field of EFI_HII_PACKAGE_GUID_HEADER.
+ Otherwise, it must be NULL.
+ @param[in] Package Points to the package referred to by the
+ notification Handle The handle of the package
+ list which contains the specified package.
+ @param[in] Handle The HII handle.
+ @param[in] NotifyType The type of change concerning the
+ database. See
+ EFI_HII_DATABASE_NOTIFY_TYPE.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformConfigFormUpdateNotify (
+ IN UINT8 PackageType,
+ IN CONST EFI_GUID *PackageGuid,
+ IN CONST EFI_HII_PACKAGE_HEADER *Package,
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
+ )
+{
+ EFI_STATUS Status;
+
+ if (NotifyType == EFI_HII_DATABASE_NOTIFY_NEW_PACK || NotifyType
== EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
+ //
+ // HII formset on this handle is updated by driver during run-time. The
formset needs to be reloaded.
+ //
+ Status = NotifyFormsetUpdate (Handle,
&mRedfishPlatformConfigPrivate->PendingList);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to notify updated formset of HII
handle: 0x%x\n", __FUNCTION__, Handle));
+ return Status;
+ }
+ } else if (NotifyType == EFI_HII_DATABASE_NOTIFY_REMOVE_PACK) {
+ //
+ // HII resource is removed. The formset is no longer exist.
+ //
+ Status = NotifyFormsetDeleted (Handle,
&mRedfishPlatformConfigPrivate->PendingList);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to notify deleted formset of HII
handle: 0x%x\n", __FUNCTION__, Handle));
+ return Status;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This is a EFI_HII_STRING_PROTOCOL notification event handler.
+
+ Install HII package notification.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context Pointer to the notification function's context.
+
+**/
+VOID
+EFIAPI
+HiiStringProtocolInstalled (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Locate HII database protocol.
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiHiiStringProtocolGuid,
+ NULL,
+ (VOID **)&mRedfishPlatformConfigPrivate->HiiString
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, locate EFI_HII_STRING_PROTOCOL failure:
%r\n", __FUNCTION__, Status));
+ return;
+ }
+
+ gBS->CloseEvent (Event);
+ mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent = NULL;
+}
+
+/**
+ This is a EFI_HII_DATABASE_PROTOCOL notification event handler.
+
+ Install HII package notification.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context Pointer to the notification function's context.
+
+**/
+VOID
+EFIAPI
+HiiDatabaseProtocolInstalled (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Locate HII database protocol.
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiHiiDatabaseProtocolGuid,
+ NULL,
+ (VOID **)&mRedfishPlatformConfigPrivate->HiiDatabase
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, locate EFI_HII_DATABASE_PROTOCOL
failure: %r\n", __FUNCTION__, Status));
+ return;
+ }
+
+ //
+ // Register package notification when new form package is installed.
+ //
+ Status = mRedfishPlatformConfigPrivate->HiiDatabase-
RegisterPackageNotify (
+ mRedfishPlatformConfigPrivate->HiiDatabase,
+ EFI_HII_PACKAGE_FORMS,
+ NULL,
+ RedfishPlatformConfigFormUpdateNotify,
+ EFI_HII_DATABASE_NOTIFY_NEW_PACK,
+ &mRedfishPlatformConfigPrivate->NotifyHandle
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for
EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__,
Status));
+ }
+
+ //
+ // Register package notification when new form package is updated.
+ //
+ Status = mRedfishPlatformConfigPrivate->HiiDatabase-
RegisterPackageNotify (
+ mRedfishPlatformConfigPrivate->HiiDatabase,
+ EFI_HII_PACKAGE_FORMS,
+ NULL,
+ RedfishPlatformConfigFormUpdateNotify,
+ EFI_HII_DATABASE_NOTIFY_ADD_PACK,
+ &mRedfishPlatformConfigPrivate->NotifyHandle
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for
EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__,
Status));
+ }
+
+ gBS->CloseEvent (Event);
+ mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent = NULL;
+
+}
+
+/**
+ This is a EFI_REGULAR_EXPRESSION_PROTOCOL notification event handler.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context Pointer to the notification function's context.
+
+**/
+VOID
+EFIAPI
+RegexProtocolInstalled (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Locate regular expression protocol.
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiRegularExpressionProtocolGuid,
+ NULL,
+ (VOID **)&mRedfishPlatformConfigPrivate-
RegularExpressionProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, locate
EFI_REGULAR_EXPRESSION_PROTOCOL failure: %r\n", __FUNCTION__,
Status));
+ return;
+ }
+
+ gBS->CloseEvent (Event);
+ mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent = NULL;
+
+}
+
+/**
+ Unloads an image.
+
+ @param ImageHandle Handle that identifies the image to be
unloaded.
+
+ @retval EFI_SUCCESS The image has been unloaded.
+ @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image
handle.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformConfigDxeUnload (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+
+ if (mRedfishPlatformConfigPrivate != NULL) {
+ Status = gBS->UninstallProtocolInterface (
+ mRedfishPlatformConfigPrivate->ImageHandle,
+ &gEdkIIRedfishPlatformConfigProtocolGuid,
+ (VOID*)&mRedfishPlatformConfigPrivate->Protocol
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, can not uninstall
gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
+ ASSERT (FALSE);
+ }
+
+ //
+ // Close events
+ //
+ if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent != NULL) {
+ gBS->CloseEvent (mRedfishPlatformConfigPrivate-
HiiDbNotify.ProtocolEvent);
+ }
+ if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent !=
NULL) {
+ gBS->CloseEvent (mRedfishPlatformConfigPrivate-
HiiStringNotify.ProtocolEvent);
+ }
+ if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent != NULL)
{
+ gBS->CloseEvent (mRedfishPlatformConfigPrivate-
RegexNotify.ProtocolEvent);
+ }
+
+ //
+ // Unregister package notification.
+ //
+ if (mRedfishPlatformConfigPrivate->NotifyHandle != NULL) {
+ mRedfishPlatformConfigPrivate->HiiDatabase->UnregisterPackageNotify
(
+ mRedfishPlatformConfigPrivate->HiiDatabase,
+ mRedfishPlatformConfigPrivate->NotifyHandle
+ );
+ }
+
+ ReleaseFormsetList (&mRedfishPlatformConfigPrivate->FormsetList);
+ FreePool (mRedfishPlatformConfigPrivate);
+ mRedfishPlatformConfigPrivate = NULL;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This is the declaration of an EFI image entry point. This entry point is
+ the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
+ both device drivers and bus drivers.
+
+ @param ImageHandle The firmware allocated handle for the UEFI
image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval Others An unexpected error occurred.
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformConfigDxeEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ mRedfishPlatformConfigPrivate = (REDFISH_PLATFORM_CONFIG_PRIVATE
*)AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PRIVATE));
+ if (mRedfishPlatformConfigPrivate == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, can not allocate pool for
REDFISH_PLATFORM_CONFIG_PRIVATE\n", __FUNCTION__));
+ ASSERT (FALSE);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Protocol initialization
+ //
+ mRedfishPlatformConfigPrivate->ImageHandle = ImageHandle;
+ mRedfishPlatformConfigPrivate->Protocol.GetValue =
RedfishPlatformConfigProtocolGetValue;
+ mRedfishPlatformConfigPrivate->Protocol.SetValue =
RedfishPlatformConfigProtocolSetValue;
+ mRedfishPlatformConfigPrivate->Protocol.GetConfigureLang =
RedfishPlatformConfigProtocolGetConfigureLang;
+ mRedfishPlatformConfigPrivate->Protocol.GetSupportedSchema =
RedfishPlatformConfigProtocolGetSupportedSchema;
+
+ InitializeListHead (&mRedfishPlatformConfigPrivate->FormsetList);
+ InitializeListHead (&mRedfishPlatformConfigPrivate->PendingList);
+
+ Status = gBS->InstallProtocolInterface (
+ &ImageHandle,
+ &gEdkIIRedfishPlatformConfigProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ (VOID*)&mRedfishPlatformConfigPrivate->Protocol
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, can not install
gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
+ ASSERT (FALSE);
+ }
+
+ //
+ // Install protocol notification if HII database protocol is installed.
+ //
+ mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent =
EfiCreateProtocolNotifyEvent (
+ &gEfiHiiDatabaseProtocolGuid,
+ TPL_CALLBACK,
+ HiiDatabaseProtocolInstalled,
+ NULL,
+ &mRedfishPlatformConfigPrivate-
HiiDbNotify.Registration
+ );
+ if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
gEfiHiiDatabaseProtocolGuid\n", __FUNCTION__));
+ ASSERT (FALSE);
+ }
+
+ //
+ // Install protocol notification if HII string protocol is installed.
+ //
+ mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent =
EfiCreateProtocolNotifyEvent (
+ &gEfiHiiStringProtocolGuid,
+ TPL_CALLBACK,
+ HiiStringProtocolInstalled,
+ NULL,
+ &mRedfishPlatformConfigPrivate-
HiiStringNotify.Registration
+ );
+ if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent == NULL)
{
+ DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
gEfiHiiStringProtocolGuid\n", __FUNCTION__));
+ ASSERT (FALSE);
+ }
+
+ //
+ // Install protocol notification if regular expression protocol is installed.
+ //
+ mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent =
EfiCreateProtocolNotifyEvent (
+ &gEfiRegularExpressionProtocolGuid,
+ TPL_CALLBACK,
+ RegexProtocolInstalled,
+ NULL,
+ &mRedfishPlatformConfigPrivate-
RegexNotify.Registration
+ );
+ if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
gEfiRegularExpressionProtocolGuid\n", __FUNCTION__));
+ ASSERT (FALSE);
+ }
+
+ return EFI_SUCCESS;
+}
diff --git
a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
index 99a613d229..d3f7af55ad 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
@@ -1,64 +1,64 @@
-/** @file
- This file defines the EDKII Redfish Platform Config Protocol interface.
-
- (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
-#define EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
-
-#include <Uefi.h>
-
-//
-// Libraries
-//
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/PrintLib.h>
-#include <Library/UefiLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiDriverEntryPoint.h>
-
-//
-// Produced Protocols
-//
-#include <Protocol/EdkIIRedfishPlatformConfig.h>
-#include <Protocol/HiiDatabase.h>
-#include <Protocol/HiiString.h>
-#include <Protocol/RegularExpressionProtocol.h>
-
-//
-// Definition of EDKII_REDFISH_PLATFORM_CONFIG_NOTIFY.
-//
-typedef struct {
- EFI_EVENT ProtocolEvent; // Protocol notification event.
- VOID *Registration; // Protocol notification registration.
-} REDFISH_PLATFORM_CONFIG_NOTIFY;
-
-//
-// Definition of REDFISH_PLATFORM_CONFIG_PRIVATE.
-//
-typedef struct {
- EFI_HANDLE ImageHandle; // Driver image handle.
- EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL Protocol;
- REDFISH_PLATFORM_CONFIG_NOTIFY HiiDbNotify;
- EFI_HII_DATABASE_PROTOCOL *HiiDatabase; // The HII
database protocol.
- REDFISH_PLATFORM_CONFIG_NOTIFY HiiStringNotify;
- EFI_HII_STRING_PROTOCOL *HiiString; // HII String
Protocol.
- REDFISH_PLATFORM_CONFIG_NOTIFY RegexNotify;
- EFI_REGULAR_EXPRESSION_PROTOCOL *RegularExpressionProtocol;
// Regular Expression Protocol.
- EFI_HANDLE NotifyHandle; // The notify handle.
- LIST_ENTRY FormsetList; // The list to keep cached
HII formset.
- LIST_ENTRY PendingList; // The list to keep updated
HII handle.
-} REDFISH_PLATFORM_CONFIG_PRIVATE;
-
-#define REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS(a) BASE_CR
(a, REDFISH_PLATFORM_CONFIG_PRIVATE, Protocol)
-#define REGULAR_EXPRESSION_INCLUDE_ALL L".*"
-#define CONFIGURE_LANGUAGE_PREFIX "x-uefi-redfish-"
-
-#endif
+/** @file
+ This file defines the EDKII Redfish Platform Config Protocol interface.
+
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
+#define EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
+
+#include <Uefi.h>
+
+//
+// Libraries
+//
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+
+//
+// Produced Protocols
+//
+#include <Protocol/EdkIIRedfishPlatformConfig.h>
+#include <Protocol/HiiDatabase.h>
+#include <Protocol/HiiString.h>
+#include <Protocol/RegularExpressionProtocol.h>
+
+//
+// Definition of EDKII_REDFISH_PLATFORM_CONFIG_NOTIFY.
+//
+typedef struct {
+ EFI_EVENT ProtocolEvent; // Protocol notification event.
+ VOID *Registration; // Protocol notification registration.
+} REDFISH_PLATFORM_CONFIG_NOTIFY;
+
+//
+// Definition of REDFISH_PLATFORM_CONFIG_PRIVATE.
+//
+typedef struct {
+ EFI_HANDLE ImageHandle; // Driver image handle.
+ EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL Protocol;
+ REDFISH_PLATFORM_CONFIG_NOTIFY HiiDbNotify;
+ EFI_HII_DATABASE_PROTOCOL *HiiDatabase; // The HII
database protocol.
+ REDFISH_PLATFORM_CONFIG_NOTIFY HiiStringNotify;
+ EFI_HII_STRING_PROTOCOL *HiiString; // HII String
Protocol.
+ REDFISH_PLATFORM_CONFIG_NOTIFY RegexNotify;
+ EFI_REGULAR_EXPRESSION_PROTOCOL *RegularExpressionProtocol;
// Regular Expression Protocol.
+ EFI_HANDLE NotifyHandle; // The notify handle.
+ LIST_ENTRY FormsetList; // The list to keep cached
HII formset.
+ LIST_ENTRY PendingList; // The list to keep updated
HII handle.
+} REDFISH_PLATFORM_CONFIG_PRIVATE;
+
+#define REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS(a) BASE_CR
(a, REDFISH_PLATFORM_CONFIG_PRIVATE, Protocol)
+#define REGULAR_EXPRESSION_INCLUDE_ALL L".*"
+#define CONFIGURE_LANGUAGE_PREFIX "x-uefi-redfish-"
+
+#endif
diff --git
a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf
b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf
index 16739bef7a..81b22e03c3 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf
@@ -1,53 +1,53 @@
-## @file
-# Implementation of EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL
interfaces.
-#
-# (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = RedfishPlatformConfigDxe
- FILE_GUID = BEAEFFE1-0633-41B5-913C-9389339C2927
- MODULE_TYPE = DXE_DRIVER
- VERSION_STRING = 1.0
- ENTRY_POINT = RedfishPlatformConfigDxeEntryPoint
- UNLOAD_IMAGE = RedfishPlatformConfigDxeUnload
-
-[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
- RedfishPkg/RedfishPkg.dec
-
-[Sources]
- RedfishPlatformConfigDxe.h
- RedfishPlatformConfigDxe.c
- RedfishPlatformConfigImpl.h
- RedfishPlatformConfigImpl.c
-
-[LibraryClasses]
- BaseLib
- BaseMemoryLib
- DebugLib
- DevicePathLib
- HiiLib
- HiiUtilityLib
- MemoryAllocationLib
- PrintLib
- UefiLib
- UefiBootServicesTableLib
- UefiRuntimeServicesTableLib
- UefiDriverEntryPoint
-
-[Protocols]
- gEdkIIRedfishPlatformConfigProtocolGuid ## PRODUCED
- gEfiHiiDatabaseProtocolGuid ## CONSUMED
- gEfiHiiStringProtocolGuid ## CONSUMED
- gEfiRegularExpressionProtocolGuid ## CONSUMED
-
-[Guids]
- gEfiRegexSyntaxTypePerlGuid ## CONSUMED
-
-[Depex]
+## @file
+# Implementation of EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL
interfaces.
+#
+# (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = RedfishPlatformConfigDxe
+ FILE_GUID = BEAEFFE1-0633-41B5-913C-9389339C2927
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = RedfishPlatformConfigDxeEntryPoint
+ UNLOAD_IMAGE = RedfishPlatformConfigDxeUnload
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ RedfishPkg/RedfishPkg.dec
+
+[Sources]
+ RedfishPlatformConfigDxe.h
+ RedfishPlatformConfigDxe.c
+ RedfishPlatformConfigImpl.h
+ RedfishPlatformConfigImpl.c
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ DevicePathLib
+ HiiLib
+ HiiUtilityLib
+ MemoryAllocationLib
+ PrintLib
+ UefiLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+ UefiDriverEntryPoint
+
+[Protocols]
+ gEdkIIRedfishPlatformConfigProtocolGuid ## PRODUCED
+ gEfiHiiDatabaseProtocolGuid ## CONSUMED
+ gEfiHiiStringProtocolGuid ## CONSUMED
+ gEfiRegularExpressionProtocolGuid ## CONSUMED
+
+[Guids]
+ gEfiRegexSyntaxTypePerlGuid ## CONSUMED
+
+[Depex]
TRUE
\ No newline at end of file
diff --git
a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
index d9eab6c883..525e666b6c 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
@@ -1,1240 +1,1288 @@
-/** @file
-
- The implementation of EDKII Redfidh Platform Config Protocol.
-
- (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-#include "RedfishPlatformConfigDxe.h"
-#include "RedfishPlatformConfigImpl.h"
-
-extern REDFISH_PLATFORM_CONFIG_PRIVATE
*mRedfishPlatformConfigPrivate;
-
-/**
- Debug dump HII string
-
- @param[in] HiiHandle HII handle instance
- @param[in] StringId HII string to dump
-
- @retval EFI_SUCCESS Dump HII string successfully
- @retval Others Errors occur
-
-**/
-EFI_STATUS
-DumpHiiString (
- IN EFI_HII_HANDLE HiiHandle,
- IN EFI_STRING_ID StringId
- )
-{
- EFI_STRING String;
-
- if (HiiHandle == NULL || StringId == 0) {
- DEBUG ((DEBUG_INFO, "???"));
- return EFI_INVALID_PARAMETER;
- }
-
- String = HiiGetString (HiiHandle, StringId, NULL);
- if (String == NULL) {
- return EFI_NOT_FOUND;
- }
-
- DEBUG ((DEBUG_INFO, "%s", String));
- FreePool (String);
-
- return EFI_SUCCESS;
-}
-
-/**
- Debug dump HII form-set data
-
- @param[in] FormsetPrivate HII form-set private instance.
-
- @retval EFI_SUCCESS Dump form-set successfully
- @retval Others Errors occur
-
-**/
-EFI_STATUS
-DumpFormset (
- IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate
- )
-{
- LIST_ENTRY *HiiFormLink;
- LIST_ENTRY *HiiNextFormLink;
- REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate;
- LIST_ENTRY *HiiStatementLink;
- LIST_ENTRY *HiiNextStatementLink;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
*HiiStatementPrivate;
- UINTN Index;
-
- if (FormsetPrivate == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- Index = 0;
- HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
- while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
- HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
(HiiFormLink);
- HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList,
HiiFormLink);
-
- DEBUG ((DEBUG_INFO, " [%d] form: %d title: ", ++Index, HiiFormPrivate-
Id));
- DumpHiiString (FormsetPrivate->HiiHandle, HiiFormPrivate->Title);
- DEBUG ((DEBUG_INFO, "\n"));
-
- HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
- while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
- HiiStatementPrivate =
REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
- HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
HiiStatementLink);
-
- DEBUG ((DEBUG_INFO, " QID: 0x%x Prompt: ", HiiStatementPrivate-
QuestionId));
- DumpHiiString (FormsetPrivate->HiiHandle, HiiStatementPrivate-
Description);
- DEBUG ((DEBUG_INFO, "\n"));
-
- HiiStatementLink = HiiNextStatementLink;
- }
-
- HiiFormLink = HiiNextFormLink;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Debug dump HII form-set list
-
- @param[in] FormsetList Form-set list instance
-
- @retval EFI_SUCCESS Dump list successfully
- @retval Others Errors occur
-
-**/
-EFI_STATUS
-DumpFormsetList (
- IN LIST_ENTRY *FormsetList
- )
-{
- LIST_ENTRY *HiiFormsetLink;
- LIST_ENTRY *HiiFormsetNextLink;
- REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
- UINTN Index;
-
- if (FormsetList == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (IsListEmpty (FormsetList)) {
- DEBUG ((DEBUG_INFO, "%a, Empty formset list\n", __FUNCTION__));
- return EFI_SUCCESS;
- }
-
- Index = 0;
- HiiFormsetLink = GetFirstNode (FormsetList);
- while (!IsNull (FormsetList, HiiFormsetLink)) {
- HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
- HiiFormsetPrivate =
REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
- DEBUG ((DEBUG_INFO, "[%d] HII Handle: 0x%x formset: %g at %s\n",
++Index, HiiFormsetPrivate->HiiHandle, &HiiFormsetPrivate->Guid,
HiiFormsetPrivate->DevicePathStr));
- DumpFormset (HiiFormsetPrivate);
-
- HiiFormsetLink = HiiFormsetNextLink;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Retrieves a string from a string package in a English language. The
- returned string is allocated using AllocatePool(). The caller is responsible
- for freeing the allocated buffer using FreePool().
-
- If HiiHandle is NULL, then ASSERT().
- If StringId is 0, then ASSET.
-
- @param[in] HiiStringProtocol EFI_HII_STRING_PROTOCOL instance.
- @param[in] HiiHandle A handle that was previously registered in the
HII Database.
- @param[in] StringId The identifier of the string to retrieved from the
string
- package associated with HiiHandle.
-
- @retval NULL The string specified by StringId is not present in the string
package.
- @retval Other The string was returned.
-
-**/
-EFI_STRING
-HiiGetRedfishString (
- IN EFI_HII_HANDLE HiiHandle,
- IN CHAR8 *Language,
- IN EFI_STRING_ID StringId
- )
-{
- EFI_STATUS Status;
- UINTN StringSize;
- CHAR16 TempString;
- EFI_STRING String;
-
- if (mRedfishPlatformConfigPrivate->HiiString == NULL || HiiHandle == NULL
|| StringId == 0 || IS_EMPTY_STRING (Language)) {
- ASSERT (FALSE);
- return NULL;
- }
-
- //
- // Retrieve the size of the string in the string package for the BestLanguage
- //
- StringSize = 0;
- Status = mRedfishPlatformConfigPrivate->HiiString->GetString (
- mRedfishPlatformConfigPrivate->HiiString,
- Language,
- HiiHandle,
- StringId,
- &TempString,
- &StringSize,
- NULL
- );
- //
- // If GetString() returns EFI_SUCCESS for a zero size,
- // then there are no supported languages registered for HiiHandle. If
GetString()
- // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is
not present
- // in the HII Database
- //
- if (Status != EFI_BUFFER_TOO_SMALL) {
- return NULL;
- }
-
- //
- // Allocate a buffer for the return string
- //
- String = AllocateZeroPool (StringSize);
- if (String == NULL) {
- return NULL;
- }
-
- //
- // Retrieve the string from the string package
- //
- Status = mRedfishPlatformConfigPrivate->HiiString->GetString (
- mRedfishPlatformConfigPrivate->HiiString,
- Language,
- HiiHandle,
- StringId,
- String,
- &StringSize,
- NULL
- );
- if (EFI_ERROR (Status)) {
- //
- // Free the buffer and return NULL if the supported languages can not be
retrieved.
- //
- FreePool (String);
- String = NULL;
- }
-
- //
- // Return the Null-terminated Unicode string
- //
- return String;
-}
-
-/**
- Get string from HII database in English language.
-
- @param[in] HiiHandle A handle that was previously registered in the
HII Database.
- @param[in] StringId The identifier of the string to retrieved from the
string
- package associated with HiiHandle.
-
- @retval NULL The string specified by StringId is not present in the string
package.
- @retval Other The string was returned.
-
-**/
-EFI_STRING
-HiiGetEnglishString (
- IN EFI_HII_HANDLE HiiHandle,
- IN EFI_STRING_ID StringId
- )
-{
- return HiiGetRedfishString (HiiHandle, ENGLISH_LANGUAGE_CODE,
StringId);
-}
-
-/**
- Check and see if this is supported schema or not.
-
- @param[in] SupportedSchema The list of supported schema.
- @param[in] Schema Schema string to be checked.
-
- @retval BOOLEAN TRUE if this is supported schema. FALSE
otherwise.
-
-**/
-BOOLEAN
-CheckSupportedSchema (
- IN REDFISH_PLATFORM_CONFIG_SCHEMA *SupportedSchema,
- IN CHAR8 *Schema
- )
-{
- UINTN Index;
-
- if (SupportedSchema == NULL || IS_EMPTY_STRING (Schema)) {
- return FALSE;
- }
-
- if (SupportedSchema->Count == 0) {
- return FALSE;
- }
-
- for (Index = 0; Index < SupportedSchema->Count; Index++) {
- if (AsciiStrCmp (SupportedSchema->SchemaList[Index], Schema) == 0) {
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-/**
- Get the list of supported schema from the given HII handle.
-
- @param[in] HiiHandle HII handle instance.
- @param[out] SupportedSchema Supported schema on this HII handle.
-
- @retval EFI_SUCCESS Schema list is returned.
- @retval EFI_INVALID_PARAMETER HiiHandle is NULL or SupportedSchema
is NULL.
- @retval EFI_NOT_FOUND No supported schema found.
- @retval EFI_OUT_OF_RESOURCES System is out of memory.
-
-**/
-EFI_STATUS
-GetSupportedSchema (
- IN EFI_HII_HANDLE HiiHandle,
- OUT REDFISH_PLATFORM_CONFIG_SCHEMA *SupportedSchema
- )
-{
- CHAR8 *SupportedLanguages;
- UINTN Index;
- UINTN LangIndex;
- UINTN Count;
- UINTN StrSize;
- UINTN ListIndex;
-
- if (HiiHandle == NULL || SupportedSchema == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- SupportedSchema->Count = 0;
-
- SupportedLanguages = HiiGetSupportedLanguages (HiiHandle);
- if (SupportedLanguages == NULL) {
- return EFI_NOT_FOUND;
- }
-
- Index = 0;
- LangIndex = 0;
- Count = 0;
- while (TRUE) {
- if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] ==
'\0') {
- if (AsciiStrnCmp (&SupportedLanguages[LangIndex],
X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
- ++Count;
- }
- LangIndex = Index + 1;
- }
-
- if (SupportedLanguages[Index] == '\0') {
- break;
- }
-
- ++Index;
- }
-
- if (Count == 0) {
- return EFI_NOT_FOUND;
- }
-
- SupportedSchema->Count = Count;
- SupportedSchema->SchemaList = AllocatePool (sizeof (CHAR8 *) * Count);
- if (SupportedSchema->SchemaList == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Index = 0;
- LangIndex = 0;
- ListIndex = 0;
- while (TRUE) {
-
- if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] ==
'\0') {
- if (AsciiStrnCmp (&SupportedLanguages[LangIndex],
X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
- StrSize = Index - LangIndex;
- SupportedSchema->SchemaList[ListIndex] = AllocateCopyPool ((StrSize
+ 1), &SupportedLanguages[LangIndex]);
- SupportedSchema->SchemaList[ListIndex][StrSize] = '\0';
- ++ListIndex;
- }
-
- LangIndex = Index + 1;
- }
-
- if (SupportedLanguages[Index] == '\0') {
- break;
- }
-
- ++Index;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Search and find statement private instance by given regular expression
patthern
- which describes the Configure Language.
-
- @param[in] RegularExpressionProtocol Regular express protocol.
- @param[in] FormsetList Form-set list to search.
- @param[in] Schema Schema to be matched.
- @param[in] Pattern Regular expression pattern.
- @param[out] StatementList Statement list that match above
pattern.
-
- @retval EFI_SUCCESS Statement list is returned.
- @retval EFI_INVALID_PARAMETER Input parameter is NULL.
- @retval EFI_NOT_READY Regular express protocol is NULL.
- @retval EFI_NOT_FOUND No statement is found.
- @retval EFI_OUT_OF_RESOURCES System is out of memory.
-
-**/
-EFI_STATUS
-GetStatementPrivateByConfigureLangRegex (
- IN EFI_REGULAR_EXPRESSION_PROTOCOL
*RegularExpressionProtocol,
- IN LIST_ENTRY *FormsetList,
- IN CHAR8 *Schema,
- IN EFI_STRING Pattern,
- OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
*StatementList
- )
-{
- LIST_ENTRY *HiiFormsetLink;
- LIST_ENTRY *HiiFormsetNextLink;
- REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
- LIST_ENTRY *HiiFormLink;
- LIST_ENTRY *HiiNextFormLink;
- REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate;
- LIST_ENTRY *HiiStatementLink;
- LIST_ENTRY *HiiNextStatementLink;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
*HiiStatementPrivate;
- EFI_STRING TmpString;
- UINTN CaptureCount;
- BOOLEAN IsMatch;
- EFI_STATUS Status;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF *StatementRef;
-
- if (FormsetList == NULL || IS_EMPTY_STRING (Schema) ||
IS_EMPTY_STRING (Pattern) || StatementList == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (RegularExpressionProtocol == NULL) {
- return EFI_NOT_READY;
- }
-
- StatementList->Count = 0;
- InitializeListHead (&StatementList->StatementList);
-
- if (IsListEmpty (FormsetList)) {
- return EFI_NOT_FOUND;
- }
-
- HiiFormsetLink = GetFirstNode (FormsetList);
- while (!IsNull (FormsetList, HiiFormsetLink)) {
- HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
- HiiFormsetPrivate =
REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
- //
- // Performance check.
- // If there is no desired Redfish schema found, skip this formset.
- //
- if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema,
Schema)) {
- HiiFormsetLink = HiiFormsetNextLink;
- continue;
- }
-
- HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
- while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
- HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList,
HiiFormLink);
- HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
(HiiFormLink);
-
- HiiStatementLink =GetFirstNode (&HiiFormPrivate->StatementList);
- while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
- HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
HiiStatementLink);
- HiiStatementPrivate =
REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
-
- if (HiiStatementPrivate->Description != 0) {
- TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle,
Schema, HiiStatementPrivate->Description);
- if (TmpString != NULL) {
- Status = RegularExpressionProtocol->MatchString (
- RegularExpressionProtocol,
- TmpString,
- Pattern,
- &gEfiRegexSyntaxTypePerlGuid,
- &IsMatch,
- NULL,
- &CaptureCount
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, MatchString \"%s\" failed: %r\n",
__FUNCTION__, Pattern, Status));
- ASSERT (FALSE);
- return Status;
- }
-
- //
- // Found
- //
- if (IsMatch) {
- StatementRef = AllocateZeroPool (sizeof
(REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF));
- if (StatementRef == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- StatementRef->Statement = HiiStatementPrivate;
- InsertTailList (&StatementList->StatementList, &StatementRef->Link);
- ++StatementList->Count;
- }
-
- FreePool (TmpString);
- }
- }
-
- HiiStatementLink = HiiNextStatementLink;
- }
-
- HiiFormLink = HiiNextFormLink;
- }
-
- HiiFormsetLink = HiiFormsetNextLink;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Get statement private instance by the given configure language.
-
- @param[in] FormsetList Form-set list to search.
- @param[in] Schema Schema to be matched.
- @param[in] ConfigureLang Configure language.
-
- @retval REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE * Pointer to
statement private instance.
-
-**/
-REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *
-GetStatementPrivateByConfigureLang (
- IN LIST_ENTRY *FormsetList,
- IN CHAR8 *Schema,
- IN EFI_STRING ConfigureLang
- )
-{
- LIST_ENTRY *HiiFormsetLink;
- LIST_ENTRY *HiiFormsetNextLink;
- REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
- LIST_ENTRY *HiiFormLink;
- LIST_ENTRY *HiiNextFormLink;
- REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate;
- LIST_ENTRY *HiiStatementLink;
- LIST_ENTRY *HiiNextStatementLink;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
*HiiStatementPrivate;
- EFI_STRING TmpString;
-
- if (FormsetList == NULL || IS_EMPTY_STRING (Schema) ||
IS_EMPTY_STRING (ConfigureLang)) {
- return NULL;
- }
-
- if (IsListEmpty (FormsetList)) {
- return NULL;
- }
-
- HiiFormsetLink = GetFirstNode (FormsetList);
- while (!IsNull (FormsetList, HiiFormsetLink)) {
- HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
- HiiFormsetPrivate =
REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
- //
- // Performance check.
- // If there is no desired Redfish schema found, skip this formset.
- //
- if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema,
Schema)) {
- HiiFormsetLink = HiiFormsetNextLink;
- continue;
- }
-
- HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
- while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
- HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList,
HiiFormLink);
- HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
(HiiFormLink);
-
- HiiStatementLink =GetFirstNode (&HiiFormPrivate->StatementList);
- while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
- HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
HiiStatementLink);
- HiiStatementPrivate =
REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
-
- DEBUG_CODE (
- STATIC UINTN Index = 0;
- DEBUG ((DEBUG_INFO, "%a, [%d] search %s in QID: 0x%x form: 0x%x
formset: %g\n", __FUNCTION__, ++Index, ConfigureLang,
HiiStatementPrivate->QuestionId, HiiFormPrivate->Id, &HiiFormsetPrivate-
Guid));
- );
-
- if (HiiStatementPrivate->Description != 0) {
- TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle,
Schema, HiiStatementPrivate->Description);
- if (TmpString != NULL) {
- if (StrCmp (TmpString, ConfigureLang) == 0) {
- FreePool (TmpString);
- return HiiStatementPrivate;
- }
-
- FreePool (TmpString);
- }
- }
-
- HiiStatementLink = HiiNextStatementLink;
- }
-
- HiiFormLink = HiiNextFormLink;
- }
-
- HiiFormsetLink = HiiFormsetNextLink;
- }
-
- return NULL;
-}
-
-/**
- Get form-set private instance by the given HII handle.
-
- @param[in] HiiHandle HII handle instance.
- @param[in] FormsetList Form-set list to search.
-
- @retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE * Pointer to
form-set private instance.
-
-**/
-REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *
-GetFormsetPrivateByHiiHandle (
- IN EFI_HII_HANDLE HiiHandle,
- IN LIST_ENTRY *FormsetList
- )
-{
- LIST_ENTRY *HiiFormsetLink;
- LIST_ENTRY *HiiFormsetNextLink;
- REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
-
- if (HiiHandle == NULL || FormsetList == NULL) {
- return NULL;
- }
-
- if (IsListEmpty (FormsetList)) {
- return NULL;
- }
-
- HiiFormsetLink = GetFirstNode (FormsetList);
- while (!IsNull (FormsetList, HiiFormsetLink)) {
- HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
- HiiFormsetPrivate =
REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
- if (HiiFormsetPrivate->HiiHandle == HiiHandle) {
- return HiiFormsetPrivate;
- }
-
- HiiFormsetLink = HiiFormsetNextLink;
- }
-
- return NULL;
-}
-
-/**
- Release formset and all the forms and statements that belong to this
formset.
-
- @param[in] FormsetPrivate Pointer to HP_HII_FORM_SET_PRIVATE
-
- @retval EFI_STATUS
-
-**/
-EFI_STATUS
-ReleaseFormset (
- IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate
- )
-{
- LIST_ENTRY *HiiFormLink;
- LIST_ENTRY *HiiNextFormLink;
- REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate;
- LIST_ENTRY *HiiStatementLink;
- LIST_ENTRY *HiiNextStatementLink;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
*HiiStatementPrivate;
- UINTN Index;
-
- if (FormsetPrivate == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
- while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
- HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
(HiiFormLink);
- HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList,
HiiFormLink);
-
- HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
- while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
- HiiStatementPrivate =
REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
- HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
HiiStatementLink);
-
- //
- // HiiStatementPrivate->HiiStatement will be released in
DestroyFormSet().
- //
-
- if (HiiStatementPrivate->DesStringCache != NULL) {
- FreePool (HiiStatementPrivate->DesStringCache);
- HiiStatementPrivate->DesStringCache = NULL;
- }
-
- RemoveEntryList (&HiiStatementPrivate->Link);
- FreePool (HiiStatementPrivate);
- HiiStatementLink = HiiNextStatementLink;
- }
-
- //
- // HiiStatementPrivate->HiiForm will be released in DestroyFormSet().
- //
-
- RemoveEntryList (&HiiFormPrivate->Link);
- FreePool (HiiFormPrivate);
- HiiFormLink = HiiNextFormLink;
- }
-
- if (FormsetPrivate->HiiFormSet != NULL) {
- DestroyFormSet (FormsetPrivate->HiiFormSet);
- FormsetPrivate->HiiFormSet = NULL;
- }
-
- FreePool (FormsetPrivate->DevicePathStr);
-
- //
- // Release schema list
- //
- if (FormsetPrivate->SupportedSchema.SchemaList != NULL) {
- for (Index = 0; Index < FormsetPrivate->SupportedSchema.Count;
Index++) {
- FreePool (FormsetPrivate->SupportedSchema.SchemaList[Index]);
- }
-
- FreePool (FormsetPrivate->SupportedSchema.SchemaList);
- FormsetPrivate->SupportedSchema.SchemaList = NULL;
- FormsetPrivate->SupportedSchema.Count = 0;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Create new form-set instance.
-
- @retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE * Pointer to
newly created form-set private instance.
-
-**/
-REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *
-NewFormsetPrivate (
- VOID
- )
-{
- REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *NewFormsetPrivate;
-
- NewFormsetPrivate = AllocateZeroPool (sizeof
(REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE));
- if (NewFormsetPrivate == NULL) {
- return NULL;
- }
-
- //
- // Initial newly created formset private data.
- //
- InitializeListHead (&NewFormsetPrivate->HiiFormList);
-
- return NewFormsetPrivate;
-}
-
-/**
- Load the HII formset from the given HII handle.
-
- @param[in] HiiHandle Target HII handle to load.
- @param[out] FormsetPrivate The formset private data.
-
- @retval EFI_STATUS
-
-**/
-EFI_STATUS
-LoadFormset (
- IN EFI_HII_HANDLE HiiHandle,
- OUT REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate
- )
-{
- EFI_STATUS Status;
- HII_FORMSET *HiiFormSet;
- HII_FORM *HiiForm;
- LIST_ENTRY *HiiFormLink;
- REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate;
- HII_STATEMENT *HiiStatement;
- LIST_ENTRY *HiiStatementLink;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
*HiiStatementPrivate;
- EFI_GUID ZeroGuid;
-
- if (HiiHandle == NULL || FormsetPrivate == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
-
- HiiFormSet = AllocateZeroPool (sizeof (HII_FORMSET));
- if (HiiFormSet == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Find HII formset by the given HII handle.
- //
- ZeroMem (&ZeroGuid, sizeof (ZeroGuid));
- Status = CreateFormSetFromHiiHandle (HiiHandle, &ZeroGuid, HiiFormSet);
- if (EFI_ERROR (Status) || IsListEmpty (&HiiFormSet->FormListHead)) {
- Status = EFI_NOT_FOUND;
- goto ErrorExit;
- }
-
- //
- // Initialize formset
- //
- InitializeFormSet (HiiFormSet);
-
- //
- // Initialize formset private data.
- //
- FormsetPrivate->HiiFormSet = HiiFormSet;
- FormsetPrivate->HiiHandle = HiiHandle;
- CopyGuid (&FormsetPrivate->Guid, &HiiFormSet->Guid);
- FormsetPrivate->DevicePathStr = ConvertDevicePathToText (HiiFormSet-
DevicePath, FALSE, FALSE);
- Status = GetSupportedSchema (FormsetPrivate->HiiHandle,
&FormsetPrivate->SupportedSchema);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_WARN, "%a, No schema from HII handle: 0x%x found:
%r\n", __FUNCTION__, FormsetPrivate->HiiHandle, Status));
- }
-
- HiiFormLink = GetFirstNode (&HiiFormSet->FormListHead);
- while (!IsNull (&HiiFormSet->FormListHead, HiiFormLink)) {
- HiiForm = HII_FORM_FROM_LINK (HiiFormLink);
-
- HiiFormPrivate = AllocateZeroPool (sizeof
(REDFISH_PLATFORM_CONFIG_FORM_PRIVATE));
- if (HiiFormPrivate == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ErrorExit;
- }
-
- //
- // Initialize form private data.
- //
- HiiFormPrivate->HiiForm = HiiForm;
- HiiFormPrivate->Id = HiiForm->FormId;
- HiiFormPrivate->Title = HiiForm->FormTitle;
- HiiFormPrivate->ParentFormset = FormsetPrivate;
- InitializeListHead (&HiiFormPrivate->StatementList);
-
- HiiStatementLink = GetFirstNode (&HiiForm->StatementListHead);
- while (!IsNull (&HiiForm->StatementListHead, HiiStatementLink)) {
- HiiStatement = HII_STATEMENT_FROM_LINK (HiiStatementLink);
-
- HiiStatementPrivate = AllocateZeroPool (sizeof
(REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE));
- if (HiiStatementPrivate == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ErrorExit;
- }
- //
- // Initialize statement private data.
- //
- HiiStatementPrivate->HiiStatement = HiiStatement;
- HiiStatementPrivate->QuestionId = HiiStatement->QuestionId;
- HiiStatementPrivate->Description = HiiStatement->Prompt;
- HiiStatementPrivate->ParentForm = HiiFormPrivate;
-
- //
- // Attach to statement list.
- //
- InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate-
Link);
- HiiStatementLink = GetNextNode (&HiiForm->StatementListHead,
HiiStatementLink);
- }
- //
- // Attach to form list.
- //
- InsertTailList (&FormsetPrivate->HiiFormList, &HiiFormPrivate->Link);
- HiiFormLink = GetNextNode (&HiiFormSet->FormListHead, HiiFormLink);
- }
-
- return EFI_SUCCESS;
-
-ErrorExit:
-
- //
- // Release HiiFormSet if HiiFormSet is not linked to FormsetPrivate yet.
- //
- if (HiiFormSet != NULL && FormsetPrivate->HiiFormSet != HiiFormSet) {
- DestroyFormSet (HiiFormSet);
- }
-
- //
- // Release resource when error happens.
- //
- ReleaseFormset (FormsetPrivate);
-
- return Status;
-}
-
-/**
- Release formset list and all the forms that belong to this formset.
-
- @param[in] FormsetList Pointer to formst list that needs to be
- released.
-
- @retval EFI_STATUS
-
-**/
-EFI_STATUS
-LoadFormsetList (
- IN EFI_HII_HANDLE *HiiHandle,
- OUT LIST_ENTRY *FormsetList
- )
-{
- EFI_STATUS Status;
- REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate;
-
- if (HiiHandle == NULL || FormsetList == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- FormsetPrivate = GetFormsetPrivateByHiiHandle (HiiHandle, FormsetList);
- if (FormsetPrivate != NULL) {
- return EFI_ALREADY_STARTED;
- }
-
- FormsetPrivate = NewFormsetPrivate ();
- if (FormsetPrivate == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__));
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Load formset on the given HII handle.
- //
- Status = LoadFormset (HiiHandle, FormsetPrivate);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to load formset: %r\n",
__FUNCTION__, Status));
- FreePool (FormsetPrivate);
- return Status;
- }
-
- //
- // Attach to cache list.
- //
- InsertTailList (FormsetList, &FormsetPrivate->Link);
-
- DEBUG_CODE (
- DumpFormsetList (FormsetList);
- );
-
- return EFI_SUCCESS;
-}
-
-/**
- Release formset list and all the forms that belong to this formset.
-
- @param[in] FormsetList Pointer to formst list that needs to be
- released.
-
- @retval EFI_STATUS
-
-**/
-EFI_STATUS
-ReleaseFormsetList (
- IN LIST_ENTRY *FormsetList
- )
-{
- LIST_ENTRY *HiiFormsetLink;
- LIST_ENTRY *HiiFormsetNextLink;
- REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
-
- if (FormsetList == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (IsListEmpty (FormsetList)) {
- return EFI_SUCCESS;
- }
-
- HiiFormsetLink = GetFirstNode (FormsetList);
- while (!IsNull (FormsetList, HiiFormsetLink)) {
- HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
- HiiFormsetPrivate =
REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
- //
- // Detach from list.
- //
- RemoveEntryList (&HiiFormsetPrivate->Link);
- ReleaseFormset (HiiFormsetPrivate);
- FreePool (HiiFormsetPrivate);
- HiiFormsetLink = HiiFormsetNextLink;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Get all pending list.
-
- @param[in] HiiHandle HII handle instance.
- @param[in] PendingList Pending list to keep pending data.
-
- @retval REDFISH_PLATFORM_CONFIG_PENDING_LIST * Pointer to
pending list data.
-
-**/
-REDFISH_PLATFORM_CONFIG_PENDING_LIST *
-GetPendingList (
- IN EFI_HII_HANDLE *HiiHandle,
- IN LIST_ENTRY *PendingList
- )
-{
- LIST_ENTRY *PendingListLink;
- REDFISH_PLATFORM_CONFIG_PENDING_LIST *Target;
-
- if (HiiHandle == NULL || PendingList == NULL) {
- return NULL;
- }
-
- if (IsListEmpty (PendingList)) {
- return NULL;
- }
-
- PendingListLink = GetFirstNode (PendingList);
- while (!IsNull (PendingList, PendingListLink)) {
- Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK
(PendingListLink);
-
- if (Target->HiiHandle == HiiHandle) {
- return Target;
- }
-
- PendingListLink = GetNextNode (PendingList, PendingListLink);
- }
-
- return NULL;
-}
-
-/**
- When HII database is updated. Keep updated HII handle into pending list so
- we can process them later.
-
- @param[in] HiiHandle HII handle instance.
- @param[in] PendingList Pending list to keep HII handle which is recently
updated.
-
- @retval EFI_SUCCESS HII handle is saved in pending list.
- @retval EFI_INVALID_PARAMETER HiiHnalde is NULL or PendingList is
NULL.
- @retval EFI_OUT_OF_RESOURCES System is out of memory.
-
-**/
-EFI_STATUS
-NotifyFormsetUpdate (
- IN EFI_HII_HANDLE *HiiHandle,
- IN LIST_ENTRY *PendingList
- )
-{
- REDFISH_PLATFORM_CONFIG_PENDING_LIST *TargetPendingList;
-
- if (HiiHandle == NULL || PendingList == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check and see if this HII handle is processed already.
- //
- TargetPendingList = GetPendingList (HiiHandle, PendingList);
- if (TargetPendingList != NULL) {
- TargetPendingList->IsDeleted = FALSE;
- DEBUG_CODE (
- DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated\n",
__FUNCTION__, HiiHandle));
- );
- return EFI_SUCCESS;
- }
-
- TargetPendingList= AllocateZeroPool (sizeof
(REDFISH_PLATFORM_CONFIG_PENDING_LIST));
- if (TargetPendingList == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- TargetPendingList->HiiHandle = HiiHandle;
- TargetPendingList->IsDeleted = FALSE;
-
- InsertTailList (PendingList, &TargetPendingList->Link);
-
- DEBUG_CODE (
- DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is created\n",
__FUNCTION__, HiiHandle));
- );
-
- return EFI_SUCCESS;
-}
-
-/**
- When HII database is updated and form-set is deleted. Keep deleted HII
handle into pending list so
- we can process them later.
-
- @param[in] HiiHandle HII handle instance.
- @param[in] PendingList Pending list to keep HII handle which is recently
updated.
-
- @retval EFI_SUCCESS HII handle is saved in pending list.
- @retval EFI_INVALID_PARAMETER HiiHnalde is NULL or PendingList is
NULL.
- @retval EFI_OUT_OF_RESOURCES System is out of memory.
-
-**/
-EFI_STATUS
-NotifyFormsetDeleted (
- IN EFI_HII_HANDLE *HiiHandle,
- IN LIST_ENTRY *PendingList
- )
-{
- REDFISH_PLATFORM_CONFIG_PENDING_LIST *TargetPendingList;
-
- if (HiiHandle == NULL || PendingList == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check and see if this HII handle is processed already.
- //
- TargetPendingList = GetPendingList (HiiHandle, PendingList);
- if (TargetPendingList != NULL) {
- TargetPendingList->IsDeleted = TRUE;
- DEBUG_CODE (
- DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated and deleted\n",
__FUNCTION__, HiiHandle));
- );
- return EFI_SUCCESS;
- }
-
- TargetPendingList= AllocateZeroPool (sizeof
(REDFISH_PLATFORM_CONFIG_PENDING_LIST));
- if (TargetPendingList == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- TargetPendingList->HiiHandle = HiiHandle;
- TargetPendingList->IsDeleted = TRUE;
-
- InsertTailList (PendingList, &TargetPendingList->Link);
-
- DEBUG_CODE (
- DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is deleted\n",
__FUNCTION__, HiiHandle));
- );
-
- return EFI_SUCCESS;
-}
-
-/**
- There are HII database update and we need to process them accordingly so
that we
- won't use stale data. This function will parse updated HII handle again in
order
- to get updated data-set.
-
- @param[in] FormsetList List to keep HII form-set.
- @param[in] PendingList List to keep HII handle that is updated.
-
- @retval EFI_SUCCESS HII handle is saved in pending list.
- @retval EFI_INVALID_PARAMETER FormsetList is NULL or PendingList is
NULL.
-
-**/
-EFI_STATUS
-ProcessPendingList (
- IN LIST_ENTRY *FormsetList,
- IN LIST_ENTRY *PendingList
- )
-{
- LIST_ENTRY *PendingListLink;
- LIST_ENTRY *PendingListNextLink;
- REDFISH_PLATFORM_CONFIG_PENDING_LIST *Target;
- REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate;
- EFI_STATUS Status;
-
-
- if (FormsetList == NULL || PendingList == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (IsListEmpty (PendingList)) {
- return EFI_SUCCESS;
- }
-
- PendingListLink = GetFirstNode (PendingList);
- while (!IsNull (PendingList, PendingListLink)) {
- PendingListNextLink = GetNextNode (PendingList, PendingListLink);
- Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK
(PendingListLink);
-
- if (Target->IsDeleted) {
- //
- // The HII resource on this HII handle is removed. Release the formset.
- //
- FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle,
FormsetList);
- if (FormsetPrivate != NULL) {
- DEBUG ((DEBUG_INFO, "%a, formset: %g is removed because driver
release HII resource it already\n", __FUNCTION__, FormsetPrivate->Guid));
- RemoveEntryList (&FormsetPrivate->Link);
- ReleaseFormset (FormsetPrivate);
- FreePool (FormsetPrivate);
- } else {
- DEBUG ((DEBUG_WARN, "%a, formset on HII handle 0x%x was removed
already\n", __FUNCTION__, Target->HiiHandle));
- }
- } else {
- //
- // The HII resource on this HII handle is updated/removed.
- //
- FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle,
FormsetList);
- if (FormsetPrivate != NULL) {
- //
- // HII formset already exist, release it and query again.
- //
- DEBUG ((DEBUG_INFO, "%a, formset: %g is updated. Release current
formset\n", __FUNCTION__, &FormsetPrivate->Guid));
- RemoveEntryList (&FormsetPrivate->Link);
- ReleaseFormset (FormsetPrivate);
- FreePool (FormsetPrivate);
- }
-
- Status = LoadFormsetList (Target->HiiHandle, FormsetList);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, load formset from HII handle: 0x%x failed:
%r\n", __FUNCTION__, Target->HiiHandle, Status));
- }
- }
-
- //
- // Detach it from list first.
- //
- RemoveEntryList (&Target->Link);
- FreePool (Target);
-
- PendingListLink = PendingListNextLink;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Release all resource in statement list.
-
- @param[in] StatementList Statement list to be released.
-
- @retval EFI_SUCCESS All resource are released.
- @retval EFI_INVALID_PARAMETER StatementList is NULL.
-
-**/
-EFI_STATUS
-ReleaseStatementList (
- IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
*StatementList
- )
-{
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF *StatementRef;
- LIST_ENTRY *NextLink;
-
- if (StatementList == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (IsListEmpty (&StatementList->StatementList)) {
- return EFI_SUCCESS;
- }
-
- NextLink = GetFirstNode (&StatementList->StatementList);
- while (!IsNull (&StatementList->StatementList, NextLink)) {
- StatementRef =
REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
- NextLink = GetNextNode (&StatementList->StatementList, NextLink);
-
- RemoveEntryList (&StatementRef->Link);
- FreePool (StatementRef);
- }
-
- return EFI_SUCCESS;
-}
+/** @file
+
+ The implementation of EDKII Redfidh Platform Config Protocol.
+
+ (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include "RedfishPlatformConfigDxe.h"
+#include "RedfishPlatformConfigImpl.h"
+
+extern REDFISH_PLATFORM_CONFIG_PRIVATE
*mRedfishPlatformConfigPrivate;
+
+/**
+ Debug dump HII string
+
+ @param[in] HiiHandle HII handle instance
+ @param[in] StringId HII string to dump
+
+ @retval EFI_SUCCESS Dump HII string successfully
+ @retval Others Errors occur
+
+**/
+EFI_STATUS
+DumpHiiString (
+ IN EFI_HII_HANDLE HiiHandle,
+ IN EFI_STRING_ID StringId
+ )
+{
+ EFI_STRING String;
+
+ if (HiiHandle == NULL || StringId == 0) {
+ DEBUG ((DEBUG_INFO, "???"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ String = HiiGetString (HiiHandle, StringId, NULL);
+ if (String == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ DEBUG ((DEBUG_INFO, "%s", String));
+ FreePool (String);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Debug dump HII form-set data
+
+ @param[in] FormsetPrivate HII form-set private instance.
+
+ @retval EFI_SUCCESS Dump form-set successfully
+ @retval Others Errors occur
+
+**/
+EFI_STATUS
+DumpFormset (
+ IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate
+ )
+{
+ LIST_ENTRY *HiiFormLink;
+ LIST_ENTRY *HiiNextFormLink;
+ REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate;
+ LIST_ENTRY *HiiStatementLink;
+ LIST_ENTRY *HiiNextStatementLink;
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
*HiiStatementPrivate;
+ UINTN Index;
+
+ if (FormsetPrivate == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Index = 0;
+ HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
+ while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
+ HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
(HiiFormLink);
+ HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList,
HiiFormLink);
+
+ DEBUG ((DEBUG_INFO, " [%d] form: %d title: ", ++Index, HiiFormPrivate-
Id));
+ DumpHiiString (FormsetPrivate->HiiHandle, HiiFormPrivate->Title);
+ DEBUG ((DEBUG_INFO, "\n"));
+
+ HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
+ while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
+ HiiStatementPrivate =
REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
+ HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
HiiStatementLink);
+
+ DEBUG ((DEBUG_INFO, " QID: 0x%x Prompt: ", HiiStatementPrivate-
QuestionId));
+ DumpHiiString (FormsetPrivate->HiiHandle, HiiStatementPrivate-
Description);
+ DEBUG ((DEBUG_INFO, "\n"));
+
+ HiiStatementLink = HiiNextStatementLink;
+ }
+
+ HiiFormLink = HiiNextFormLink;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Debug dump HII form-set list
+
+ @param[in] FormsetList Form-set list instance
+
+ @retval EFI_SUCCESS Dump list successfully
+ @retval Others Errors occur
+
+**/
+EFI_STATUS
+DumpFormsetList (
+ IN LIST_ENTRY *FormsetList
+ )
+{
+ LIST_ENTRY *HiiFormsetLink;
+ LIST_ENTRY *HiiFormsetNextLink;
+ REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
+ UINTN Index;
+
+ if (FormsetList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (IsListEmpty (FormsetList)) {
+ DEBUG ((DEBUG_INFO, "%a, Empty formset list\n", __FUNCTION__));
+ return EFI_SUCCESS;
+ }
+
+ Index = 0;
+ HiiFormsetLink = GetFirstNode (FormsetList);
+ while (!IsNull (FormsetList, HiiFormsetLink)) {
+ HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
+ HiiFormsetPrivate =
REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+ DEBUG ((DEBUG_INFO, "[%d] HII Handle: 0x%x formset: %g at %s\n",
++Index, HiiFormsetPrivate->HiiHandle, &HiiFormsetPrivate->Guid,
HiiFormsetPrivate->DevicePathStr));
+ DumpFormset (HiiFormsetPrivate);
+
+ HiiFormsetLink = HiiFormsetNextLink;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Retrieves a unicode string from a string package in a given language. The
+ returned string is allocated using AllocatePool(). The caller is responsible
+ for freeing the allocated buffer using FreePool().
+
+ If HiiHandle is NULL, then ASSERT().
+ If StringId is 0, then ASSET.
+
+ @param[in] HiiHandle A handle that was previously registered in the
HII Database.
+ @param[in] Language The specified configure language to get string.
+ @param[in] StringId The identifier of the string to retrieved from the
string
+ package associated with HiiHandle.
+
+ @retval NULL The string specified by StringId is not present in the string
package.
+ @retval Other The string was returned.
+
+**/
+EFI_STRING
+HiiGetRedfishString (
+ IN EFI_HII_HANDLE HiiHandle,
+ IN CHAR8 *Language,
+ IN EFI_STRING_ID StringId
+ )
+{
+ EFI_STATUS Status;
+ UINTN StringSize;
+ CHAR16 TempString;
+ EFI_STRING String;
+
+ if (mRedfishPlatformConfigPrivate->HiiString == NULL || HiiHandle ==
NULL || StringId == 0 || IS_EMPTY_STRING (Language)) {
+ ASSERT (FALSE);
+ return NULL;
+ }
+
+ //
+ // Retrieve the size of the string in the string package for the BestLanguage
+ //
+ StringSize = 0;
+ Status = mRedfishPlatformConfigPrivate->HiiString->GetString (
+ mRedfishPlatformConfigPrivate->HiiString,
+ Language,
+ HiiHandle,
+ StringId,
+ &TempString,
+ &StringSize,
+ NULL
+ );
+ //
+ // If GetString() returns EFI_SUCCESS for a zero size,
+ // then there are no supported languages registered for HiiHandle. If
GetString()
+ // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is
not present
+ // in the HII Database
+ //
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ return NULL;
+ }
+
+ //
+ // Allocate a buffer for the return string
+ //
+ String = AllocateZeroPool (StringSize);
+ if (String == NULL) {
+ return NULL;
+ }
+
+ //
+ // Retrieve the string from the string package
+ //
+ Status = mRedfishPlatformConfigPrivate->HiiString->GetString (
+ mRedfishPlatformConfigPrivate->HiiString,
+ Language,
+ HiiHandle,
+ StringId,
+ String,
+ &StringSize,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // Free the buffer and return NULL if the supported languages can not be
retrieved.
+ //
+ FreePool (String);
+ String = NULL;
+ }
+
+ //
+ // Return the Null-terminated Unicode string
+ //
+ return String;
+}
+
+/**
+ Retrieves a ASCII string from a string package in a given language. The
+ returned string is allocated using AllocatePool(). The caller is responsible
+ for freeing the allocated buffer using FreePool().
+
+ If HiiHandle is NULL, then ASSERT().
+ If StringId is 0, then ASSET.
+
+ @param[in] HiiHandle A handle that was previously registered in the
HII Database.
+ @param[in] Language The specified configure language to get string.
+ @param[in] StringId The identifier of the string to retrieved from the
string
+ package associated with HiiHandle.
+
+ @retval NULL The string specified by StringId is not present in the string
package.
+ @retval Other The string was returned.
+
+**/
+CHAR8 *
+HiiGetRedfishAsciiString (
+ IN EFI_HII_HANDLE HiiHandle,
+ IN CHAR8 *Language,
+ IN EFI_STRING_ID StringId
+ )
+{
+ EFI_STRING HiiString;
+ UINTN StringSize;
+ CHAR8 *AsciiString;
+
+ HiiString = HiiGetRedfishString (HiiHandle, Language, StringId);
+ if (HiiString == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, Can not find string ID: 0x%x with %a\n",
__FUNCTION__, StringId, Language));
+ return NULL;
+ }
+
+ StringSize = (StrLen (HiiString) + 1) * sizeof (CHAR8);
+ AsciiString = AllocatePool (StringSize);
+ if (AsciiString == NULL) {
+ return NULL;
+ }
+
+ UnicodeStrToAsciiStrS (HiiString, AsciiString, StringSize);
+
+ FreePool (HiiString);
+ return AsciiString;
+}
+
+/**
+ Get string from HII database in English language.
+
+ @param[in] HiiHandle A handle that was previously registered in the
HII Database.
+ @param[in] StringId The identifier of the string to retrieved from the
string
+ package associated with HiiHandle.
+
+ @retval NULL The string specified by StringId is not present in the string
package.
+ @retval Other The string was returned.
+
+**/
+EFI_STRING
+HiiGetEnglishString (
+ IN EFI_HII_HANDLE HiiHandle,
+ IN EFI_STRING_ID StringId
+ )
+{
+ return HiiGetRedfishString (HiiHandle, ENGLISH_LANGUAGE_CODE,
StringId);
+}
+
+/**
+ Check and see if this is supported schema or not.
+
+ @param[in] SupportedSchema The list of supported schema.
+ @param[in] Schema Schema string to be checked.
+
+ @retval BOOLEAN TRUE if this is supported schema. FALSE
otherwise.
+
+**/
+BOOLEAN
+CheckSupportedSchema (
+ IN REDFISH_PLATFORM_CONFIG_SCHEMA *SupportedSchema,
+ IN CHAR8 *Schema
+ )
+{
+ UINTN Index;
+
+ if (SupportedSchema == NULL || IS_EMPTY_STRING (Schema)) {
+ return FALSE;
+ }
+
+ if (SupportedSchema->Count == 0) {
+ return FALSE;
+ }
+
+ for (Index = 0; Index < SupportedSchema->Count; Index++) {
+ if (AsciiStrCmp (SupportedSchema->SchemaList[Index], Schema) == 0) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ Get the list of supported schema from the given HII handle.
+
+ @param[in] HiiHandle HII handle instance.
+ @param[out] SupportedSchema Supported schema on this HII handle.
+
+ @retval EFI_SUCCESS Schema list is returned.
+ @retval EFI_INVALID_PARAMETER HiiHandle is NULL or SupportedSchema
is NULL.
+ @retval EFI_NOT_FOUND No supported schema found.
+ @retval EFI_OUT_OF_RESOURCES System is out of memory.
+
+**/
+EFI_STATUS
+GetSupportedSchema (
+ IN EFI_HII_HANDLE HiiHandle,
+ OUT REDFISH_PLATFORM_CONFIG_SCHEMA *SupportedSchema
+ )
+{
+ CHAR8 *SupportedLanguages;
+ UINTN Index;
+ UINTN LangIndex;
+ UINTN Count;
+ UINTN StrSize;
+ UINTN ListIndex;
+
+ if (HiiHandle == NULL || SupportedSchema == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ SupportedSchema->Count = 0;
+
+ SupportedLanguages = HiiGetSupportedLanguages (HiiHandle);
+ if (SupportedLanguages == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ Index = 0;
+ LangIndex = 0;
+ Count = 0;
+ while (TRUE) {
+ if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] ==
'\0') {
+ if (AsciiStrnCmp (&SupportedLanguages[LangIndex],
X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
+ ++Count;
+ }
+ LangIndex = Index + 1;
+ }
+
+ if (SupportedLanguages[Index] == '\0') {
+ break;
+ }
+
+ ++Index;
+ }
+
+ if (Count == 0) {
+ return EFI_NOT_FOUND;
+ }
+
+ SupportedSchema->Count = Count;
+ SupportedSchema->SchemaList = AllocatePool (sizeof (CHAR8 *) * Count);
+ if (SupportedSchema->SchemaList == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Index = 0;
+ LangIndex = 0;
+ ListIndex = 0;
+ while (TRUE) {
+
+ if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] ==
'\0') {
+ if (AsciiStrnCmp (&SupportedLanguages[LangIndex],
X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
+ StrSize = Index - LangIndex;
+ SupportedSchema->SchemaList[ListIndex] = AllocateCopyPool ((StrSize
+ 1), &SupportedLanguages[LangIndex]);
+ SupportedSchema->SchemaList[ListIndex][StrSize] = '\0';
+ ++ListIndex;
+ }
+
+ LangIndex = Index + 1;
+ }
+
+ if (SupportedLanguages[Index] == '\0') {
+ break;
+ }
+
+ ++Index;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Search and find statement private instance by given regular expression
patthern
+ which describes the Configure Language.
+
+ @param[in] RegularExpressionProtocol Regular express protocol.
+ @param[in] FormsetList Form-set list to search.
+ @param[in] Schema Schema to be matched.
+ @param[in] Pattern Regular expression pattern.
+ @param[out] StatementList Statement list that match above
pattern.
+
+ @retval EFI_SUCCESS Statement list is returned.
+ @retval EFI_INVALID_PARAMETER Input parameter is NULL.
+ @retval EFI_NOT_READY Regular express protocol is NULL.
+ @retval EFI_NOT_FOUND No statement is found.
+ @retval EFI_OUT_OF_RESOURCES System is out of memory.
+
+**/
+EFI_STATUS
+GetStatementPrivateByConfigureLangRegex (
+ IN EFI_REGULAR_EXPRESSION_PROTOCOL
*RegularExpressionProtocol,
+ IN LIST_ENTRY *FormsetList,
+ IN CHAR8 *Schema,
+ IN EFI_STRING Pattern,
+ OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
*StatementList
+ )
+{
+ LIST_ENTRY *HiiFormsetLink;
+ LIST_ENTRY *HiiFormsetNextLink;
+ REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
+ LIST_ENTRY *HiiFormLink;
+ LIST_ENTRY *HiiNextFormLink;
+ REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate;
+ LIST_ENTRY *HiiStatementLink;
+ LIST_ENTRY *HiiNextStatementLink;
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
*HiiStatementPrivate;
+ EFI_STRING TmpString;
+ UINTN CaptureCount;
+ BOOLEAN IsMatch;
+ EFI_STATUS Status;
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF *StatementRef;
+
+ if (FormsetList == NULL || IS_EMPTY_STRING (Schema) ||
IS_EMPTY_STRING (Pattern) || StatementList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (RegularExpressionProtocol == NULL) {
+ return EFI_NOT_READY;
+ }
+
+ StatementList->Count = 0;
+ InitializeListHead (&StatementList->StatementList);
+
+ if (IsListEmpty (FormsetList)) {
+ return EFI_NOT_FOUND;
+ }
+
+ HiiFormsetLink = GetFirstNode (FormsetList);
+ while (!IsNull (FormsetList, HiiFormsetLink)) {
+ HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
+ HiiFormsetPrivate =
REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+ //
+ // Performance check.
+ // If there is no desired Redfish schema found, skip this formset.
+ //
+ if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema,
Schema)) {
+ HiiFormsetLink = HiiFormsetNextLink;
+ continue;
+ }
+
+ HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
+ while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
+ HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList,
HiiFormLink);
+ HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
(HiiFormLink);
+
+ HiiStatementLink =GetFirstNode (&HiiFormPrivate->StatementList);
+ while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
+ HiiNextStatementLink = GetNextNode (&HiiFormPrivate-
StatementList, HiiStatementLink);
+ HiiStatementPrivate =
REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
+
+ if (HiiStatementPrivate->Description != 0) {
+ TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle,
Schema, HiiStatementPrivate->Description);
+ if (TmpString != NULL) {
+ Status = RegularExpressionProtocol->MatchString (
+ RegularExpressionProtocol,
+ TmpString,
+ Pattern,
+ &gEfiRegexSyntaxTypePerlGuid,
+ &IsMatch,
+ NULL,
+ &CaptureCount
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, MatchString \"%s\" failed: %r\n",
__FUNCTION__, Pattern, Status));
+ ASSERT (FALSE);
+ return Status;
+ }
+
+ //
+ // Found
+ //
+ if (IsMatch) {
+ StatementRef = AllocateZeroPool (sizeof
(REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF));
+ if (StatementRef == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ StatementRef->Statement = HiiStatementPrivate;
+ InsertTailList (&StatementList->StatementList, &StatementRef-
Link);
+ ++StatementList->Count;
+ }
+
+ FreePool (TmpString);
+ }
+ }
+
+ HiiStatementLink = HiiNextStatementLink;
+ }
+
+ HiiFormLink = HiiNextFormLink;
+ }
+
+ HiiFormsetLink = HiiFormsetNextLink;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Get statement private instance by the given configure language.
+
+ @param[in] FormsetList Form-set list to search.
+ @param[in] Schema Schema to be matched.
+ @param[in] ConfigureLang Configure language.
+
+ @retval REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE * Pointer
to statement private instance.
+
+**/
+REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *
+GetStatementPrivateByConfigureLang (
+ IN LIST_ENTRY *FormsetList,
+ IN CHAR8 *Schema,
+ IN EFI_STRING ConfigureLang
+ )
+{
+ LIST_ENTRY *HiiFormsetLink;
+ LIST_ENTRY *HiiFormsetNextLink;
+ REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
+ LIST_ENTRY *HiiFormLink;
+ LIST_ENTRY *HiiNextFormLink;
+ REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate;
+ LIST_ENTRY *HiiStatementLink;
+ LIST_ENTRY *HiiNextStatementLink;
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
*HiiStatementPrivate;
+ EFI_STRING TmpString;
+
+ if (FormsetList == NULL || IS_EMPTY_STRING (Schema) ||
IS_EMPTY_STRING (ConfigureLang)) {
+ return NULL;
+ }
+
+ if (IsListEmpty (FormsetList)) {
+ return NULL;
+ }
+
+ HiiFormsetLink = GetFirstNode (FormsetList);
+ while (!IsNull (FormsetList, HiiFormsetLink)) {
+ HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
+ HiiFormsetPrivate =
REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+ //
+ // Performance check.
+ // If there is no desired Redfish schema found, skip this formset.
+ //
+ if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema,
Schema)) {
+ HiiFormsetLink = HiiFormsetNextLink;
+ continue;
+ }
+
+ HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
+ while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
+ HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList,
HiiFormLink);
+ HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
(HiiFormLink);
+
+ HiiStatementLink =GetFirstNode (&HiiFormPrivate->StatementList);
+ while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
+ HiiNextStatementLink = GetNextNode (&HiiFormPrivate-
StatementList, HiiStatementLink);
+ HiiStatementPrivate =
REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
+
+ DEBUG_CODE (
+ STATIC UINTN Index = 0;
+ DEBUG ((DEBUG_INFO, "%a, [%d] search %s in QID: 0x%x form: 0x%x
formset: %g\n", __FUNCTION__, ++Index, ConfigureLang,
HiiStatementPrivate->QuestionId, HiiFormPrivate->Id, &HiiFormsetPrivate-
Guid));
+ );
+
+ if (HiiStatementPrivate->Description != 0) {
+ TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle,
Schema, HiiStatementPrivate->Description);
+ if (TmpString != NULL) {
+ if (StrCmp (TmpString, ConfigureLang) == 0) {
+ FreePool (TmpString);
+ return HiiStatementPrivate;
+ }
+
+ FreePool (TmpString);
+ }
+ }
+
+ HiiStatementLink = HiiNextStatementLink;
+ }
+
+ HiiFormLink = HiiNextFormLink;
+ }
+
+ HiiFormsetLink = HiiFormsetNextLink;
+ }
+
+ return NULL;
+}
+
+/**
+ Get form-set private instance by the given HII handle.
+
+ @param[in] HiiHandle HII handle instance.
+ @param[in] FormsetList Form-set list to search.
+
+ @retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE * Pointer to
form-set private instance.
+
+**/
+REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *
+GetFormsetPrivateByHiiHandle (
+ IN EFI_HII_HANDLE HiiHandle,
+ IN LIST_ENTRY *FormsetList
+ )
+{
+ LIST_ENTRY *HiiFormsetLink;
+ LIST_ENTRY *HiiFormsetNextLink;
+ REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
+
+ if (HiiHandle == NULL || FormsetList == NULL) {
+ return NULL;
+ }
+
+ if (IsListEmpty (FormsetList)) {
+ return NULL;
+ }
+
+ HiiFormsetLink = GetFirstNode (FormsetList);
+ while (!IsNull (FormsetList, HiiFormsetLink)) {
+ HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
+ HiiFormsetPrivate =
REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+ if (HiiFormsetPrivate->HiiHandle == HiiHandle) {
+ return HiiFormsetPrivate;
+ }
+
+ HiiFormsetLink = HiiFormsetNextLink;
+ }
+
+ return NULL;
+}
+
+/**
+ Release formset and all the forms and statements that belong to this
formset.
+
+ @param[in] FormsetPrivate Pointer to HP_HII_FORM_SET_PRIVATE
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+ReleaseFormset (
+ IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate
+ )
+{
+ LIST_ENTRY *HiiFormLink;
+ LIST_ENTRY *HiiNextFormLink;
+ REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate;
+ LIST_ENTRY *HiiStatementLink;
+ LIST_ENTRY *HiiNextStatementLink;
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
*HiiStatementPrivate;
+ UINTN Index;
+
+ if (FormsetPrivate == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
+ while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
+ HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
(HiiFormLink);
+ HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList,
HiiFormLink);
+
+ HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
+ while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
+ HiiStatementPrivate =
REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
+ HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
HiiStatementLink);
+
+ //
+ // HiiStatementPrivate->HiiStatement will be released in
DestroyFormSet().
+ //
+
+ if (HiiStatementPrivate->DesStringCache != NULL) {
+ FreePool (HiiStatementPrivate->DesStringCache);
+ HiiStatementPrivate->DesStringCache = NULL;
+ }
+
+ RemoveEntryList (&HiiStatementPrivate->Link);
+ FreePool (HiiStatementPrivate);
+ HiiStatementLink = HiiNextStatementLink;
+ }
+
+ //
+ // HiiStatementPrivate->HiiForm will be released in DestroyFormSet().
+ //
+
+ RemoveEntryList (&HiiFormPrivate->Link);
+ FreePool (HiiFormPrivate);
+ HiiFormLink = HiiNextFormLink;
+ }
+
+ if (FormsetPrivate->HiiFormSet != NULL) {
+ DestroyFormSet (FormsetPrivate->HiiFormSet);
+ FormsetPrivate->HiiFormSet = NULL;
+ }
+
+ if (FormsetPrivate->DevicePathStr != NULL) {
+ FreePool(FormsetPrivate->DevicePathStr);
+ }
+
+ //
+ // Release schema list
+ //
+ if (FormsetPrivate->SupportedSchema.SchemaList != NULL) {
+ for (Index = 0; Index < FormsetPrivate->SupportedSchema.Count;
Index++) {
+ FreePool (FormsetPrivate->SupportedSchema.SchemaList[Index]);
+ }
+
+ FreePool (FormsetPrivate->SupportedSchema.SchemaList);
+ FormsetPrivate->SupportedSchema.SchemaList = NULL;
+ FormsetPrivate->SupportedSchema.Count = 0;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Create new form-set instance.
+
+ @retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE * Pointer to
newly created form-set private instance.
+
+**/
+REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *
+NewFormsetPrivate (
+ VOID
+ )
+{
+ REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *NewFormsetPrivate;
+
+ NewFormsetPrivate = AllocateZeroPool (sizeof
(REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE));
+ if (NewFormsetPrivate == NULL) {
+ return NULL;
+ }
+
+ //
+ // Initial newly created formset private data.
+ //
+ InitializeListHead (&NewFormsetPrivate->HiiFormList);
+
+ return NewFormsetPrivate;
+}
+
+/**
+ Load the HII formset from the given HII handle.
+
+ @param[in] HiiHandle Target HII handle to load.
+ @param[out] FormsetPrivate The formset private data.
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+LoadFormset (
+ IN EFI_HII_HANDLE HiiHandle,
+ OUT REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE
*FormsetPrivate
+ )
+{
+ EFI_STATUS Status;
+ HII_FORMSET *HiiFormSet;
+ HII_FORM *HiiForm;
+ LIST_ENTRY *HiiFormLink;
+ REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate;
+ HII_STATEMENT *HiiStatement;
+ LIST_ENTRY *HiiStatementLink;
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
*HiiStatementPrivate;
+ EFI_GUID ZeroGuid;
+
+ if (HiiHandle == NULL || FormsetPrivate == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+
+ HiiFormSet = AllocateZeroPool (sizeof (HII_FORMSET));
+ if (HiiFormSet == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Find HII formset by the given HII handle.
+ //
+ ZeroMem (&ZeroGuid, sizeof (ZeroGuid));
+ Status = CreateFormSetFromHiiHandle (HiiHandle, &ZeroGuid, HiiFormSet);
+ if (EFI_ERROR (Status) || IsListEmpty (&HiiFormSet->FormListHead)) {
+ Status = EFI_NOT_FOUND;
+ goto ErrorExit;
+ }
+
+ //
+ // Initialize formset
+ //
+ InitializeFormSet (HiiFormSet);
+
+ //
+ // Initialize formset private data.
+ //
+ FormsetPrivate->HiiFormSet = HiiFormSet;
+ FormsetPrivate->HiiHandle = HiiHandle;
+ CopyGuid (&FormsetPrivate->Guid, &HiiFormSet->Guid);
+ FormsetPrivate->DevicePathStr = ConvertDevicePathToText (HiiFormSet-
DevicePath, FALSE, FALSE);
+ Status = GetSupportedSchema (FormsetPrivate->HiiHandle,
&FormsetPrivate->SupportedSchema);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_WARN, "%a, No schema from HII handle: 0x%x found:
%r\n", __FUNCTION__, FormsetPrivate->HiiHandle, Status));
+ }
+
+ HiiFormLink = GetFirstNode (&HiiFormSet->FormListHead);
+ while (!IsNull (&HiiFormSet->FormListHead, HiiFormLink)) {
+ HiiForm = HII_FORM_FROM_LINK (HiiFormLink);
+
+ HiiFormPrivate = AllocateZeroPool (sizeof
(REDFISH_PLATFORM_CONFIG_FORM_PRIVATE));
+ if (HiiFormPrivate == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ErrorExit;
+ }
+
+ //
+ // Initialize form private data.
+ //
+ HiiFormPrivate->HiiForm = HiiForm;
+ HiiFormPrivate->Id = HiiForm->FormId;
+ HiiFormPrivate->Title = HiiForm->FormTitle;
+ HiiFormPrivate->ParentFormset = FormsetPrivate;
+ InitializeListHead (&HiiFormPrivate->StatementList);
+
+ HiiStatementLink = GetFirstNode (&HiiForm->StatementListHead);
+ while (!IsNull (&HiiForm->StatementListHead, HiiStatementLink)) {
+ HiiStatement = HII_STATEMENT_FROM_LINK (HiiStatementLink);
+
+ HiiStatementPrivate = AllocateZeroPool (sizeof
(REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE));
+ if (HiiStatementPrivate == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ErrorExit;
+ }
+ //
+ // Initialize statement private data.
+ //
+ HiiStatementPrivate->HiiStatement = HiiStatement;
+ HiiStatementPrivate->QuestionId = HiiStatement->QuestionId;
+ HiiStatementPrivate->Description = HiiStatement->Prompt;
+ HiiStatementPrivate->ParentForm = HiiFormPrivate;
+
+ //
+ // Attach to statement list.
+ //
+ InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate-
Link);
+ HiiStatementLink = GetNextNode (&HiiForm->StatementListHead,
HiiStatementLink);
+ }
+ //
+ // Attach to form list.
+ //
+ InsertTailList (&FormsetPrivate->HiiFormList, &HiiFormPrivate->Link);
+ HiiFormLink = GetNextNode (&HiiFormSet->FormListHead, HiiFormLink);
+ }
+
+ return EFI_SUCCESS;
+
+ErrorExit:
+
+ //
+ // Release HiiFormSet if HiiFormSet is not linked to FormsetPrivate yet.
+ //
+ if (HiiFormSet != NULL && FormsetPrivate->HiiFormSet != HiiFormSet) {
+ DestroyFormSet (HiiFormSet);
+ }
+
+ //
+ // Release resource when error happens.
+ //
+ ReleaseFormset (FormsetPrivate);
+
+ return Status;
+}
+
+/**
+ Release formset list and all the forms that belong to this formset.
+
+ @param[in] FormsetList Pointer to formst list that needs to be
+ released.
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+LoadFormsetList (
+ IN EFI_HII_HANDLE *HiiHandle,
+ OUT LIST_ENTRY *FormsetList
+ )
+{
+ EFI_STATUS Status;
+ REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate;
+
+ if (HiiHandle == NULL || FormsetList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FormsetPrivate = GetFormsetPrivateByHiiHandle (HiiHandle, FormsetList);
+ if (FormsetPrivate != NULL) {
+ return EFI_ALREADY_STARTED;
+ }
+
+ FormsetPrivate = NewFormsetPrivate ();
+ if (FormsetPrivate == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Load formset on the given HII handle.
+ //
+ Status = LoadFormset (HiiHandle, FormsetPrivate);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to load formset: %r\n",
__FUNCTION__, Status));
+ FreePool (FormsetPrivate);
+ return Status;
+ }
+
+ //
+ // Attach to cache list.
+ //
+ InsertTailList (FormsetList, &FormsetPrivate->Link);
+
+ DEBUG_CODE (
+ DumpFormsetList (FormsetList);
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Release formset list and all the forms that belong to this formset.
+
+ @param[in] FormsetList Pointer to formst list that needs to be
+ released.
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+ReleaseFormsetList (
+ IN LIST_ENTRY *FormsetList
+ )
+{
+ LIST_ENTRY *HiiFormsetLink;
+ LIST_ENTRY *HiiFormsetNextLink;
+ REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
+
+ if (FormsetList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (IsListEmpty (FormsetList)) {
+ return EFI_SUCCESS;
+ }
+
+ HiiFormsetLink = GetFirstNode (FormsetList);
+ while (!IsNull (FormsetList, HiiFormsetLink)) {
+ HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
+ HiiFormsetPrivate =
REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+ //
+ // Detach from list.
+ //
+ RemoveEntryList (&HiiFormsetPrivate->Link);
+ ReleaseFormset (HiiFormsetPrivate);
+ FreePool (HiiFormsetPrivate);
+ HiiFormsetLink = HiiFormsetNextLink;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Get all pending list.
+
+ @param[in] HiiHandle HII handle instance.
+ @param[in] PendingList Pending list to keep pending data.
+
+ @retval REDFISH_PLATFORM_CONFIG_PENDING_LIST * Pointer to
pending list data.
+
+**/
+REDFISH_PLATFORM_CONFIG_PENDING_LIST *
+GetPendingList (
+ IN EFI_HII_HANDLE *HiiHandle,
+ IN LIST_ENTRY *PendingList
+ )
+{
+ LIST_ENTRY *PendingListLink;
+ REDFISH_PLATFORM_CONFIG_PENDING_LIST *Target;
+
+ if (HiiHandle == NULL || PendingList == NULL) {
+ return NULL;
+ }
+
+ if (IsListEmpty (PendingList)) {
+ return NULL;
+ }
+
+ PendingListLink = GetFirstNode (PendingList);
+ while (!IsNull (PendingList, PendingListLink)) {
+ Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK
(PendingListLink);
+
+ if (Target->HiiHandle == HiiHandle) {
+ return Target;
+ }
+
+ PendingListLink = GetNextNode (PendingList, PendingListLink);
+ }
+
+ return NULL;
+}
+
+/**
+ When HII database is updated. Keep updated HII handle into pending list
so
+ we can process them later.
+
+ @param[in] HiiHandle HII handle instance.
+ @param[in] PendingList Pending list to keep HII handle which is recently
updated.
+
+ @retval EFI_SUCCESS HII handle is saved in pending list.
+ @retval EFI_INVALID_PARAMETER HiiHnalde is NULL or PendingList is
NULL.
+ @retval EFI_OUT_OF_RESOURCES System is out of memory.
+
+**/
+EFI_STATUS
+NotifyFormsetUpdate (
+ IN EFI_HII_HANDLE *HiiHandle,
+ IN LIST_ENTRY *PendingList
+ )
+{
+ REDFISH_PLATFORM_CONFIG_PENDING_LIST *TargetPendingList;
+
+ if (HiiHandle == NULL || PendingList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check and see if this HII handle is processed already.
+ //
+ TargetPendingList = GetPendingList (HiiHandle, PendingList);
+ if (TargetPendingList != NULL) {
+ TargetPendingList->IsDeleted = FALSE;
+ DEBUG_CODE (
+ DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated\n",
__FUNCTION__, HiiHandle));
+ );
+ return EFI_SUCCESS;
+ }
+
+ TargetPendingList= AllocateZeroPool (sizeof
(REDFISH_PLATFORM_CONFIG_PENDING_LIST));
+ if (TargetPendingList == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ TargetPendingList->HiiHandle = HiiHandle;
+ TargetPendingList->IsDeleted = FALSE;
+
+ InsertTailList (PendingList, &TargetPendingList->Link);
+
+ DEBUG_CODE (
+ DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is created\n",
__FUNCTION__, HiiHandle));
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ When HII database is updated and form-set is deleted. Keep deleted HII
handle into pending list so
+ we can process them later.
+
+ @param[in] HiiHandle HII handle instance.
+ @param[in] PendingList Pending list to keep HII handle which is recently
updated.
+
+ @retval EFI_SUCCESS HII handle is saved in pending list.
+ @retval EFI_INVALID_PARAMETER HiiHnalde is NULL or PendingList is
NULL.
+ @retval EFI_OUT_OF_RESOURCES System is out of memory.
+
+**/
+EFI_STATUS
+NotifyFormsetDeleted (
+ IN EFI_HII_HANDLE *HiiHandle,
+ IN LIST_ENTRY *PendingList
+ )
+{
+ REDFISH_PLATFORM_CONFIG_PENDING_LIST *TargetPendingList;
+
+ if (HiiHandle == NULL || PendingList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check and see if this HII handle is processed already.
+ //
+ TargetPendingList = GetPendingList (HiiHandle, PendingList);
+ if (TargetPendingList != NULL) {
+ TargetPendingList->IsDeleted = TRUE;
+ DEBUG_CODE (
+ DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated and deleted\n",
__FUNCTION__, HiiHandle));
+ );
+ return EFI_SUCCESS;
+ }
+
+ TargetPendingList= AllocateZeroPool (sizeof
(REDFISH_PLATFORM_CONFIG_PENDING_LIST));
+ if (TargetPendingList == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ TargetPendingList->HiiHandle = HiiHandle;
+ TargetPendingList->IsDeleted = TRUE;
+
+ InsertTailList (PendingList, &TargetPendingList->Link);
+
+ DEBUG_CODE (
+ DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is deleted\n",
__FUNCTION__, HiiHandle));
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ There are HII database update and we need to process them accordingly
so that we
+ won't use stale data. This function will parse updated HII handle again in
order
+ to get updated data-set.
+
+ @param[in] FormsetList List to keep HII form-set.
+ @param[in] PendingList List to keep HII handle that is updated.
+
+ @retval EFI_SUCCESS HII handle is saved in pending list.
+ @retval EFI_INVALID_PARAMETER FormsetList is NULL or PendingList is
NULL.
+
+**/
+EFI_STATUS
+ProcessPendingList (
+ IN LIST_ENTRY *FormsetList,
+ IN LIST_ENTRY *PendingList
+ )
+{
+ LIST_ENTRY *PendingListLink;
+ LIST_ENTRY *PendingListNextLink;
+ REDFISH_PLATFORM_CONFIG_PENDING_LIST *Target;
+ REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate;
+ EFI_STATUS Status;
+
+
+ if (FormsetList == NULL || PendingList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (IsListEmpty (PendingList)) {
+ return EFI_SUCCESS;
+ }
+
+ PendingListLink = GetFirstNode (PendingList);
+ while (!IsNull (PendingList, PendingListLink)) {
+ PendingListNextLink = GetNextNode (PendingList, PendingListLink);
+ Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK
(PendingListLink);
+
+ if (Target->IsDeleted) {
+ //
+ // The HII resource on this HII handle is removed. Release the formset.
+ //
+ FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle,
FormsetList);
+ if (FormsetPrivate != NULL) {
+ DEBUG ((DEBUG_INFO, "%a, formset: %g is removed because driver
release HII resource it already\n", __FUNCTION__, FormsetPrivate->Guid));
+ RemoveEntryList (&FormsetPrivate->Link);
+ ReleaseFormset (FormsetPrivate);
+ FreePool (FormsetPrivate);
+ } else {
+ DEBUG ((DEBUG_WARN, "%a, formset on HII handle 0x%x was
removed already\n", __FUNCTION__, Target->HiiHandle));
+ }
+ } else {
+ //
+ // The HII resource on this HII handle is updated/removed.
+ //
+ FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle,
FormsetList);
+ if (FormsetPrivate != NULL) {
+ //
+ // HII formset already exist, release it and query again.
+ //
+ DEBUG ((DEBUG_INFO, "%a, formset: %g is updated. Release current
formset\n", __FUNCTION__, &FormsetPrivate->Guid));
+ RemoveEntryList (&FormsetPrivate->Link);
+ ReleaseFormset (FormsetPrivate);
+ FreePool (FormsetPrivate);
+ }
+
+ Status = LoadFormsetList (Target->HiiHandle, FormsetList);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, load formset from HII handle: 0x%x
failed: %r\n", __FUNCTION__, Target->HiiHandle, Status));
+ }
+ }
+
+ //
+ // Detach it from list first.
+ //
+ RemoveEntryList (&Target->Link);
+ FreePool (Target);
+
+ PendingListLink = PendingListNextLink;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Release all resource in statement list.
+
+ @param[in] StatementList Statement list to be released.
+
+ @retval EFI_SUCCESS All resource are released.
+ @retval EFI_INVALID_PARAMETER StatementList is NULL.
+
+**/
+EFI_STATUS
+ReleaseStatementList (
+ IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
*StatementList
+ )
+{
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF *StatementRef;
+ LIST_ENTRY *NextLink;
+
+ if (StatementList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (IsListEmpty (&StatementList->StatementList)) {
+ return EFI_SUCCESS;
+ }
+
+ NextLink = GetFirstNode (&StatementList->StatementList);
+ while (!IsNull (&StatementList->StatementList, NextLink)) {
+ StatementRef =
REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
+ NextLink = GetNextNode (&StatementList->StatementList, NextLink);
+
+ RemoveEntryList (&StatementRef->Link);
+ FreePool (StatementRef);
+ }
+
+ return EFI_SUCCESS;
+}
diff --git
a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
index e0ba0fb2d3..cd7a52aef3 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
@@ -1,274 +1,297 @@
-/** @file
- This file defines the EDKII Redfish Platform Config Protocol interface.
-
- (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_
-#define EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_
-
-#include <Uefi.h>
-
-//
-// Libraries
-//
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/DevicePathLib.h>
-#include <Library/HiiUtilityLib.h>
-#include <Library/HiiLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiLib.h>
-
-#define REDFISH_PLATFORM_CONFIG_DELETE_EXPIRED_FORMSET 0x00
-#define IS_EMPTY_STRING(a) (a == NULL || a[0] == L'\0')
-#define ENGLISH_LANGUAGE_CODE "en-US"
-#define X_UEFI_SCHEMA_PREFIX "x-uefi-redfish-"
-
-//
-// Definition of REDFISH_PLATFORM_CONFIG_PRIVATE.
-//
-typedef struct {
- LIST_ENTRY Link;
- EFI_HII_HANDLE HiiHandle;
- BOOLEAN IsDeleted;
-} REDFISH_PLATFORM_CONFIG_PENDING_LIST;
-
-#define REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK(a)
BASE_CR (a, REDFISH_PLATFORM_CONFIG_PENDING_LIST, Link)
-
-typedef struct {
- UINTN Count; // Number of schema in list
- CHAR8 **SchemaList; // Schema list
-} REDFISH_PLATFORM_CONFIG_SCHEMA;
-
-//
-// Definition of REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE
-//
-typedef struct {
- LIST_ENTRY Link;
- HII_FORMSET *HiiFormSet; // Pointer to HII formset data.
- EFI_GUID Guid; // Formset GUID.
- EFI_HII_HANDLE HiiHandle; // Hii Handle of this formset.
- LIST_ENTRY HiiFormList; // Form list that keep form data under
this formset.
- CHAR16 *DevicePathStr; // Device path of this formset.
- REDFISH_PLATFORM_CONFIG_SCHEMA SupportedSchema; // Schema
that is supported in this formset.
-} REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE;
-
-#define REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK(a) BASE_CR
(a, REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE, Link)
-
-//
-// Definition of REDFISH_PLATFORM_CONFIG_FORM_PRIVATE
-//
-typedef struct {
- LIST_ENTRY Link;
- UINT16 Id; // Form ID.
- EFI_STRING_ID Title; // String token of form title.
- REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *ParentFormset;
- HII_FORM *HiiForm; // Pointer to HII form data.
- LIST_ENTRY StatementList; // Statement list that keep
statement under this form.
-} REDFISH_PLATFORM_CONFIG_FORM_PRIVATE;
-
-#define REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK(a) BASE_CR (a,
REDFISH_PLATFORM_CONFIG_FORM_PRIVATE, Link)
-
-//
-// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
-//
-typedef struct {
- LIST_ENTRY Link;
- REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *ParentForm;
- HII_STATEMENT *HiiStatement; // Pointer to HII statement
data.
- EFI_QUESTION_ID QuestionId; // Question ID of this
statement.
- EFI_STRING_ID Description; // String token of this question.
- EFI_STRING DesStringCache; // The string cache for search
function.
-} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE;
-
-#define REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK(a)
BASE_CR (a, REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE, Link)
-
-//
-// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF
-//
-typedef struct {
- LIST_ENTRY Link;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement;
-} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF;
-
-#define REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK(a)
BASE_CR (a, REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF, Link)
-
-//
-// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
-//
-typedef struct {
- LIST_ENTRY StatementList; // List of
REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF
- UINTN Count;
-} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST;
-
-/**
- Release formset list and all the forms that belong to this formset.
-
- @param[in] FormsetList Pointer to formst list that needs to be
- released.
-
- @retval EFI_STATUS
-
-**/
-EFI_STATUS
-ReleaseFormsetList (
- IN LIST_ENTRY *FormsetList
- );
-
-/**
- Release formset list and all the forms that belong to this formset.
-
- @param[in] FormsetList Pointer to formst list that needs to be
- released.
-
- @retval EFI_STATUS
-
-**/
-EFI_STATUS
-LoadFormsetList (
- IN EFI_HII_HANDLE *HiiHandle,
- OUT LIST_ENTRY *FormsetList
- );
-
-/**
- When HII database is updated. Keep updated HII handle into pending list so
- we can process them later.
-
- @param[in] HiiHandle HII handle instance.
- @param[in] PendingList Pending list to keep HII handle which is recently
updated.
-
- @retval EFI_SUCCESS HII handle is saved in pending list.
- @retval EFI_INVALID_PARAMETER HiiHnalde is NULL or PendingList is
NULL.
- @retval EFI_OUT_OF_RESOURCES System is out of memory.
-
-**/
-EFI_STATUS
-NotifyFormsetUpdate (
- IN EFI_HII_HANDLE *HiiHandle,
- IN LIST_ENTRY *PendingList
- );
-
-/**
- When HII database is updated and form-set is deleted. Keep deleted HII
handle into pending list so
- we can process them later.
-
- @param[in] HiiHandle HII handle instance.
- @param[in] PendingList Pending list to keep HII handle which is recently
updated.
-
- @retval EFI_SUCCESS HII handle is saved in pending list.
- @retval EFI_INVALID_PARAMETER HiiHnalde is NULL or PendingList is
NULL.
- @retval EFI_OUT_OF_RESOURCES System is out of memory.
-
-**/
-EFI_STATUS
-NotifyFormsetDeleted (
- IN EFI_HII_HANDLE *HiiHandle,
- IN LIST_ENTRY *PendingList
- );
-
-/**
- Get statement private instance by the given configure language.
-
- @param[in] FormsetList Form-set list to search.
- @param[in] Schema Schema to be matched.
- @param[in] ConfigureLang Configure language.
-
- @retval REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE * Pointer to
statement private instance.
-
-**/
-REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *
-GetStatementPrivateByConfigureLang (
- IN LIST_ENTRY *FormsetList,
- IN CHAR8 *Schema,
- IN EFI_STRING ConfigureLang
- );
-
-/**
- Search and find statement private instance by given regular expression
patthern
- which describes the Configure Language.
-
- @param[in] RegularExpressionProtocol Regular express protocol.
- @param[in] FormsetList Form-set list to search.
- @param[in] Schema Schema to be matched.
- @param[in] Pattern Regular expression pattern.
- @param[out] StatementList Statement list that match above
pattern.
-
- @retval EFI_SUCCESS Statement list is returned.
- @retval EFI_INVALID_PARAMETER Input parameter is NULL.
- @retval EFI_NOT_READY Regular express protocol is NULL.
- @retval EFI_NOT_FOUND No statement is found.
- @retval EFI_OUT_OF_RESOURCES System is out of memory.
-
-**/
-EFI_STATUS
-GetStatementPrivateByConfigureLangRegex (
- IN EFI_REGULAR_EXPRESSION_PROTOCOL
*RegularExpressionProtocol,
- IN LIST_ENTRY *FormsetList,
- IN CHAR8 *Schema,
- IN EFI_STRING Pattern,
- OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
*StatementList
- );
-
-/**
- There are HII database update and we need to process them accordingly so
that we
- won't use stale data. This function will parse updated HII handle again in
order
- to get updated data-set.
-
- @param[in] FormsetList List to keep HII form-set.
- @param[in] PendingList List to keep HII handle that is updated.
-
- @retval EFI_SUCCESS HII handle is saved in pending list.
- @retval EFI_INVALID_PARAMETER FormsetList is NULL or PendingList is
NULL.
-
-**/
-EFI_STATUS
-ProcessPendingList (
- IN LIST_ENTRY *FormsetList,
- IN LIST_ENTRY *PendingList
- );
-
-/**
- Retrieves a string from a string package in a English language. The
- returned string is allocated using AllocatePool(). The caller is responsible
- for freeing the allocated buffer using FreePool().
-
- If HiiHandle is NULL, then ASSERT().
- If StringId is 0, then ASSET.
-
- @param[in] HiiStringProtocol EFI_HII_STRING_PROTOCOL instance.
- @param[in] HiiHandle A handle that was previously registered in the
HII Database.
- @param[in] StringId The identifier of the string to retrieved from the
string
- package associated with HiiHandle.
-
- @retval NULL The string specified by StringId is not present in the string
package.
- @retval Other The string was returned.
-
-**/
-EFI_STRING
-HiiGetRedfishString (
- IN EFI_HII_HANDLE HiiHandle,
- IN CHAR8 *Language,
- IN EFI_STRING_ID StringId
- );
-
-/**
- Release all resource in statement list.
-
- @param[in] StatementList Statement list to be released.
-
- @retval EFI_SUCCESS All resource are released.
- @retval EFI_INVALID_PARAMETER StatementList is NULL.
-
-**/
-EFI_STATUS
-ReleaseStatementList (
- IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
*StatementList
- );
-
-#endif
+/** @file
+ This file defines the EDKII Redfish Platform Config Protocol interface.
+
+ (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_
+#define EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_
+
+#include <Uefi.h>
+
+//
+// Libraries
+//
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiUtilityLib.h>
+#include <Library/HiiLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+#define IS_EMPTY_STRING(a) (a == NULL || a[0] == L'\0')
+#define ENGLISH_LANGUAGE_CODE "en-US"
+#define X_UEFI_SCHEMA_PREFIX "x-uefi-redfish-"
+
+//
+// Definition of REDFISH_PLATFORM_CONFIG_PRIVATE.
+//
+typedef struct {
+ LIST_ENTRY Link;
+ EFI_HII_HANDLE HiiHandle;
+ BOOLEAN IsDeleted;
+} REDFISH_PLATFORM_CONFIG_PENDING_LIST;
+
+#define REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK(a)
BASE_CR (a, REDFISH_PLATFORM_CONFIG_PENDING_LIST, Link)
+
+typedef struct {
+ UINTN Count; // Number of schema in list
+ CHAR8 **SchemaList; // Schema list
+} REDFISH_PLATFORM_CONFIG_SCHEMA;
+
+//
+// Definition of REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE
+//
+typedef struct {
+ LIST_ENTRY Link;
+ HII_FORMSET *HiiFormSet; // Pointer to HII formset data.
+ EFI_GUID Guid; // Formset GUID.
+ EFI_HII_HANDLE HiiHandle; // Hii Handle of this formset.
+ LIST_ENTRY HiiFormList; // Form list that keep form data under
this formset.
+ CHAR16 *DevicePathStr; // Device path of this formset.
+ REDFISH_PLATFORM_CONFIG_SCHEMA SupportedSchema; // Schema
that is supported in this formset.
+} REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE;
+
+#define REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK(a) BASE_CR
(a, REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE, Link)
+
+//
+// Definition of REDFISH_PLATFORM_CONFIG_FORM_PRIVATE
+//
+typedef struct {
+ LIST_ENTRY Link;
+ UINT16 Id; // Form ID.
+ EFI_STRING_ID Title; // String token of form title.
+ REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *ParentFormset;
+ HII_FORM *HiiForm; // Pointer to HII form data.
+ LIST_ENTRY StatementList; // Statement list that keep
statement under this form.
+} REDFISH_PLATFORM_CONFIG_FORM_PRIVATE;
+
+#define REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK(a) BASE_CR (a,
REDFISH_PLATFORM_CONFIG_FORM_PRIVATE, Link)
+
+//
+// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
+//
+typedef struct {
+ LIST_ENTRY Link;
+ REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *ParentForm;
+ HII_STATEMENT *HiiStatement; // Pointer to HII statement
data.
+ EFI_QUESTION_ID QuestionId; // Question ID of this
statement.
+ EFI_STRING_ID Description; // String token of this question.
+ EFI_STRING DesStringCache; // The string cache for search
function.
+} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE;
+
+#define REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK(a)
BASE_CR (a, REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE, Link)
+
+//
+// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF
+//
+typedef struct {
+ LIST_ENTRY Link;
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement;
+} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF;
+
+#define REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK(a)
BASE_CR (a, REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF, Link)
+
+//
+// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
+//
+typedef struct {
+ LIST_ENTRY StatementList; // List of
REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF
+ UINTN Count;
+} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST;
+
+/**
+ Release formset list and all the forms that belong to this formset.
+
+ @param[in] FormsetList Pointer to formst list that needs to be
+ released.
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+ReleaseFormsetList (
+ IN LIST_ENTRY *FormsetList
+ );
+
+/**
+ Release formset list and all the forms that belong to this formset.
+
+ @param[in] FormsetList Pointer to formst list that needs to be
+ released.
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+LoadFormsetList (
+ IN EFI_HII_HANDLE *HiiHandle,
+ OUT LIST_ENTRY *FormsetList
+ );
+
+/**
+ When HII database is updated. Keep updated HII handle into pending list
so
+ we can process them later.
+
+ @param[in] HiiHandle HII handle instance.
+ @param[in] PendingList Pending list to keep HII handle which is recently
updated.
+
+ @retval EFI_SUCCESS HII handle is saved in pending list.
+ @retval EFI_INVALID_PARAMETER HiiHnalde is NULL or PendingList is
NULL.
+ @retval EFI_OUT_OF_RESOURCES System is out of memory.
+
+**/
+EFI_STATUS
+NotifyFormsetUpdate (
+ IN EFI_HII_HANDLE *HiiHandle,
+ IN LIST_ENTRY *PendingList
+ );
+
+/**
+ When HII database is updated and form-set is deleted. Keep deleted HII
handle into pending list so
+ we can process them later.
+
+ @param[in] HiiHandle HII handle instance.
+ @param[in] PendingList Pending list to keep HII handle which is recently
updated.
+
+ @retval EFI_SUCCESS HII handle is saved in pending list.
+ @retval EFI_INVALID_PARAMETER HiiHnalde is NULL or PendingList is
NULL.
+ @retval EFI_OUT_OF_RESOURCES System is out of memory.
+
+**/
+EFI_STATUS
+NotifyFormsetDeleted (
+ IN EFI_HII_HANDLE *HiiHandle,
+ IN LIST_ENTRY *PendingList
+ );
+
+/**
+ Get statement private instance by the given configure language.
+
+ @param[in] FormsetList Form-set list to search.
+ @param[in] Schema Schema to be matched.
+ @param[in] ConfigureLang Configure language.
+
+ @retval REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE * Pointer
to statement private instance.
+
+**/
+REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *
+GetStatementPrivateByConfigureLang (
+ IN LIST_ENTRY *FormsetList,
+ IN CHAR8 *Schema,
+ IN EFI_STRING ConfigureLang
+ );
+
+/**
+ Search and find statement private instance by given regular expression
patthern
+ which describes the Configure Language.
+
+ @param[in] RegularExpressionProtocol Regular express protocol.
+ @param[in] FormsetList Form-set list to search.
+ @param[in] Schema Schema to be matched.
+ @param[in] Pattern Regular expression pattern.
+ @param[out] StatementList Statement list that match above
pattern.
+
+ @retval EFI_SUCCESS Statement list is returned.
+ @retval EFI_INVALID_PARAMETER Input parameter is NULL.
+ @retval EFI_NOT_READY Regular express protocol is NULL.
+ @retval EFI_NOT_FOUND No statement is found.
+ @retval EFI_OUT_OF_RESOURCES System is out of memory.
+
+**/
+EFI_STATUS
+GetStatementPrivateByConfigureLangRegex (
+ IN EFI_REGULAR_EXPRESSION_PROTOCOL
*RegularExpressionProtocol,
+ IN LIST_ENTRY *FormsetList,
+ IN CHAR8 *Schema,
+ IN EFI_STRING Pattern,
+ OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
*StatementList
+ );
+
+/**
+ There are HII database update and we need to process them accordingly
so that we
+ won't use stale data. This function will parse updated HII handle again in
order
+ to get updated data-set.
+
+ @param[in] FormsetList List to keep HII form-set.
+ @param[in] PendingList List to keep HII handle that is updated.
+
+ @retval EFI_SUCCESS HII handle is saved in pending list.
+ @retval EFI_INVALID_PARAMETER FormsetList is NULL or PendingList is
NULL.
+
+**/
+EFI_STATUS
+ProcessPendingList (
+ IN LIST_ENTRY *FormsetList,
+ IN LIST_ENTRY *PendingList
+ );
+
+/**
+ Retrieves a unicode string from a string package in a given language. The
+ returned string is allocated using AllocatePool(). The caller is responsible
+ for freeing the allocated buffer using FreePool().
+
+ If HiiHandle is NULL, then ASSERT().
+ If StringId is 0, then ASSET.
+
+ @param[in] HiiHandle A handle that was previously registered in the
HII Database.
+ @param[in] Language The specified configure language to get string.
+ @param[in] StringId The identifier of the string to retrieved from the
string
+ package associated with HiiHandle.
+
+ @retval NULL The string specified by StringId is not present in the string
package.
+ @retval Other The string was returned.
+
+**/
+EFI_STRING
+HiiGetRedfishString (
+ IN EFI_HII_HANDLE HiiHandle,
+ IN CHAR8 *Language,
+ IN EFI_STRING_ID StringId
+ );
+
+/**
+ Retrieves a ASCII string from a string package in a given language. The
+ returned string is allocated using AllocatePool(). The caller is responsible
+ for freeing the allocated buffer using FreePool().
+
+ If HiiHandle is NULL, then ASSERT().
+ If StringId is 0, then ASSET.
+
+ @param[in] HiiHandle A handle that was previously registered in the
HII Database.
+ @param[in] Language The specified configure language to get string.
+ @param[in] StringId The identifier of the string to retrieved from the
string
+ package associated with HiiHandle.
+
+ @retval NULL The string specified by StringId is not present in the string
package.
+ @retval Other The string was returned.
+
+**/
+CHAR8 *
+HiiGetRedfishAsciiString (
+ IN EFI_HII_HANDLE HiiHandle,
+ IN CHAR8 *Language,
+ IN EFI_STRING_ID StringId
+ );
+
+/**
+ Release all resource in statement list.
+
+ @param[in] StatementList Statement list to be released.
+
+ @retval EFI_SUCCESS All resource are released.
+ @retval EFI_INVALID_PARAMETER StatementList is NULL.
+
+**/
+EFI_STATUS
+ReleaseStatementList (
+ IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
*StatementList
+ );
+
+#endif
--
2.32.0.windows.2


Re: [edk2-staging][PATCH v2 1/1] edk2/RedfishPkg: Update Redfish Platform Config Protocol

Nickle Wang
 

Thanks Abner! Fixed in version 3.

Nickle

-----Original Message-----
From: Chang, Abner <Abner.Chang@...>
Sent: Sunday, July 24, 2022 9:46 PM
To: Wang, Nickle (Server BIOS) <nickle.wang@...>; devel@edk2.groups.io
Cc: Yang, Atom <Atom.Yang@...>; Nick Ramirez <nramirez@...>
Subject: RE: [edk2-staging][PATCH v2 1/1] edk2/RedfishPkg: Update Redfish Platform Config Protocol

[AMD Official Use Only - General]

Thanks Nickle. Two comments in the below.

-----Original Message-----
From: Nickle Wang <nickle.wang@...>
Sent: Sunday, July 24, 2022 9:20 PM
To: devel@edk2.groups.io
Cc: Chang, Abner <Abner.Chang@...>; Yang, Atom
<Atom.Yang@...>; Nick Ramirez <nramirez@...>
Subject: [edk2-staging][PATCH v2 1/1] edk2/RedfishPkg: Update Redfish
Platform Config Protocol

[CAUTION: External Email]

Update EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL and add array type
of
value support to EDKII_REDFISH_VALUE in order to support ordered list
op-code in HII. Modify corresponding function to support new type of
data structure.

Signed-off-by: Nickle Wang <nickle.wang@...>
Cc: Abner Chang <abner.chang@...>
Cc: Yang Atom <Atom.Yang@...>
Cc: Nick Ramirez <nramirez@...>
---
.../Protocol/EdkIIRedfishPlatformConfig.h | 301 +-
.../RedfishPlatformConfigDxe.c | 3087 ++++++++++-------
.../RedfishPlatformConfigDxe.h | 128 +-
.../RedfishPlatformConfigDxe.inf | 104 +-
.../RedfishPlatformConfigImpl.c | 2528 +++++++-------
.../RedfishPlatformConfigImpl.h | 571 +--
6 files changed, 3638 insertions(+), 3081 deletions(-)

diff --git a/RedfishPkg/Include/Protocol/EdkIIRedfishPlatformConfig.h
b/RedfishPkg/Include/Protocol/EdkIIRedfishPlatformConfig.h
index 895b010227..bbbab90b03 100644
--- a/RedfishPkg/Include/Protocol/EdkIIRedfishPlatformConfig.h
+++ b/RedfishPkg/Include/Protocol/EdkIIRedfishPlatformConfig.h
@@ -1,147 +1,154 @@
-/** @file
- This file defines the EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL
interface.
-
- (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef EDKII_REDFISH_PLATFORM_CONFIG_H_
-#define EDKII_REDFISH_PLATFORM_CONFIG_H_
-
-typedef struct _EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL;
-
-/**
- Definition of EDKII_REDFISH_TYPE_VALUE
- **/
-typedef union {
- INT64 Integer;
- BOOLEAN Boolean;
- CHAR8 *Buffer;
-} EDKII_REDFISH_TYPE_VALUE;
-
-/**
- Definition of EDKII_REDFISH_VALUE_TYPES
- **/
-typedef enum {
- REDFISH_VALUE_TYPE_UNKNOWN = 0,
- REDFISH_VALUE_TYPE_INTEGER,
- REDFISH_VALUE_TYPE_BOOLEAN,
- REDFISH_VALUE_TYPE_STRING,
- REDFISH_VALUE_TYPE_MAX
-} EDKII_REDFISH_VALUE_TYPES;
-
-/**
- Definition of EDKII_REDFISH_VALUE
- **/
-typedef struct {
- EDKII_REDFISH_VALUE_TYPES Type;
- EDKII_REDFISH_TYPE_VALUE Value;
-} EDKII_REDFISH_VALUE;
-
-/**
- Get Redfish value with the given Schema and Configure Language.
-
- @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
- @param[in] Schema The Redfish schema to query.
- @param[in] Version The Redfish version to query.
- @param[in] ConfigureLang The target value which match this configure
Language.
- @param[out] Value The returned value.
-
- @retval EFI_SUCCESS Value is returned successfully.
- @retval Others Some error happened.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_VALUE) (
- IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
- IN CHAR8 *Schema,
- IN CHAR8 *Version,
- IN EFI_STRING ConfigureLang,
- OUT EDKII_REDFISH_VALUE *Value
- );
-
-/**
- Set Redfish value with the given Schema and Configure Language.
-
- @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
- @param[in] Schema The Redfish schema to query.
- @param[in] Version The Redfish version to query.
- @param[in] ConfigureLang The target value which match this configure
Language.
- @param[in] Value The value to set.
-
- @retval EFI_SUCCESS Value is returned successfully.
- @retval Others Some error happened.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_SET_VALUE) (
- IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
- IN CHAR8 *Schema,
- IN CHAR8 *Version,
- IN EFI_STRING ConfigureLang,
- IN EDKII_REDFISH_VALUE Value
- );
-
-/**
- Get the list of Configure Language from platform configuration by the given
Schema and Pattern.
-
- @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
- @param[in] Schema The Redfish schema to query.
- @param[in] Version The Redfish version to query.
- @param[in] Pattern The target Configure Language pattern.
- @param[out] ConfigureLangList The list of Configure Language.
- @param[out] Count The number of Configure Language in
ConfigureLangList.
-
- @retval EFI_SUCCESS ConfigureLangList is returned successfully.
- @retval Others Some error happened.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_CONFIG_LANG) (
- IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
- IN CHAR8 *Schema,
- IN CHAR8 *Version,
- IN EFI_STRING Pattern,
- OUT EFI_STRING **ConfigureLangList,
- OUT UINTN *Count
- );
-
-
-/**
- Get the list of supported Redfish schema from platform configuration on
the give HII handle.
-
- @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
- @param[in] HiiHandle The target handle to search. If handle is NULL,
- this function returns all schema from HII database.
- @param[out] SupportedSchema The supported schema list which is
separated by ';'.
- For example: "x-uefi-redfish-Memory.v1_7_1;x-uefi-
redfish-Boot.v1_0_1"
- The SupportedSchema is allocated by the callee. It's caller's
- responsibility to free this buffer using FreePool().
-
- @retval EFI_SUCCESS Schema is returned successfully.
- @retval Others Some error happened.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_SUPPORTED_SCHEMA)
(
- IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
- IN EFI_HII_HANDLE HiiHandle, OPTIONAL
- OUT CHAR8 **SupportedSchema
- );
-
-struct _EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL {
- EDKII_REDFISH_PLATFORM_CONFIG_GET_VALUE GetValue;
- EDKII_REDFISH_PLATFORM_CONFIG_SET_VALUE SetValue;
- EDKII_REDFISH_PLATFORM_CONFIG_GET_CONFIG_LANG
GetConfigureLang;
- EDKII_REDFISH_PLATFORM_CONFIG_GET_SUPPORTED_SCHEMA
GetSupportedSchema;
-};
-
-extern EFI_GUID gEdkIIRedfishPlatformConfigProtocolGuid;
-
-#endif
+/** @file
+ This file defines the EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL
interface.
+
+ (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef EDKII_REDFISH_PLATFORM_CONFIG_H_
+#define EDKII_REDFISH_PLATFORM_CONFIG_H_
+
+typedef struct _EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL;
+
+/**
+ Definition of EDKII_REDFISH_TYPE_VALUE
+ **/
+typedef union {
+ INT64 Integer;
+ BOOLEAN Boolean;
+ CHAR8 *Buffer;
+ CHAR8 **StringArray;
+ INT64 *IntegerArray;
+ BOOLEAN *BooleanArray;
+} EDKII_REDFISH_TYPE_VALUE;
+
+/**
+ Definition of EDKII_REDFISH_VALUE_TYPES
+ **/
+typedef enum {
+ REDFISH_VALUE_TYPE_UNKNOWN = 0,
+ REDFISH_VALUE_TYPE_INTEGER,
+ REDFISH_VALUE_TYPE_BOOLEAN,
+ REDFISH_VALUE_TYPE_STRING,
+ REDFISH_VALUE_TYPE_STRING_ARRAY,
+ REDFISH_VALUE_TYPE_INTEGER_ARRAY,
+ REDFISH_VALUE_TYPE_BOOLEAN_ARRAY,
+ REDFISH_VALUE_TYPE_MAX
+} EDKII_REDFISH_VALUE_TYPES;
+
+/**
+ Definition of EDKII_REDFISH_VALUE
+ **/
+typedef struct {
+ EDKII_REDFISH_VALUE_TYPES Type;
+ EDKII_REDFISH_TYPE_VALUE Value;
+ UINTN ArrayCount;
+} EDKII_REDFISH_VALUE;
+
+/**
+ Get Redfish value with the given Schema and Configure Language.
+
+ @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+ @param[in] Schema The Redfish schema to query.
+ @param[in] Version The Redfish version to query.
+ @param[in] ConfigureLang The target value which match this configure
Language.
+ @param[out] Value The returned value.
+
+ @retval EFI_SUCCESS Value is returned successfully.
+ @retval Others Some error happened.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_VALUE) (
+ IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+ IN CHAR8 *Schema,
+ IN CHAR8 *Version,
+ IN EFI_STRING ConfigureLang,
+ OUT EDKII_REDFISH_VALUE *Value
+ );
+
+/**
+ Set Redfish value with the given Schema and Configure Language.
+
+ @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+ @param[in] Schema The Redfish schema to query.
+ @param[in] Version The Redfish version to query.
+ @param[in] ConfigureLang The target value which match this configure
Language.
+ @param[in] Value The value to set.
+
+ @retval EFI_SUCCESS Value is returned successfully.
+ @retval Others Some error happened.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_SET_VALUE) (
+ IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+ IN CHAR8 *Schema,
+ IN CHAR8 *Version,
+ IN EFI_STRING ConfigureLang,
+ IN EDKII_REDFISH_VALUE Value
+ );
+
+/**
+ Get the list of Configure Language from platform configuration by the
given Schema and RegexPattern.
+
+ @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+ @param[in] Schema The Redfish schema to query.
+ @param[in] Version The Redfish version to query.
+ @param[in] RegexPattern The target Configure Language pattern.
This is used for regular expression matching.
+ @param[out] ConfigureLangList The list of Configure Language.
+ @param[out] Count The number of Configure Language in
ConfigureLangList.
+
+ @retval EFI_SUCCESS ConfigureLangList is returned successfully.
+ @retval Others Some error happened.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_CONFIG_LANG) (
+ IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+ IN CHAR8 *Schema,
+ IN CHAR8 *Version,
+ IN EFI_STRING RegexPattern,
+ OUT EFI_STRING **ConfigureLangList,
+ OUT UINTN *Count
+ );
+
+
+/**
+ Get the list of supported Redfish schema from platform configuration on
the give HII handle.
+
+ @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+ @param[in] HiiHandle The target handle to search. If handle is NULL,
+ this function returns all schema from HII database.
+ @param[out] SupportedSchema The supported schema list which is
separated by ';'.
+ For example: "x-uefi-redfish-Memory.v1_7_1;x-uefi-
redfish-Boot.v1_0_1"
+ The SupportedSchema is allocated by the callee. It's
caller's
+ responsibility to free this buffer using FreePool().
+
+ @retval EFI_SUCCESS Schema is returned successfully.
+ @retval Others Some error happened.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_SUPPORTED_SCHEMA)
(
+ IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+ IN EFI_HII_HANDLE HiiHandle, OPTIONAL
+ OUT CHAR8 **SupportedSchema
+ );
+
+struct _EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL {
+ EDKII_REDFISH_PLATFORM_CONFIG_GET_VALUE GetValue;
+ EDKII_REDFISH_PLATFORM_CONFIG_SET_VALUE SetValue;
+ EDKII_REDFISH_PLATFORM_CONFIG_GET_CONFIG_LANG
GetConfigureLang;
+ EDKII_REDFISH_PLATFORM_CONFIG_GET_SUPPORTED_SCHEMA
GetSupportedSchema;
+};
+
+extern EFI_GUID gEdkIIRedfishPlatformConfigProtocolGuid;
+
+#endif
diff --git
a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
index 67818cccd2..971035f27d 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
@@ -1,1304 +1,1783 @@
-/** @file
-
- The implementation of EDKII Redfidh Platform Config Protocol.
-
- (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "RedfishPlatformConfigDxe.h"
-#include "RedfishPlatformConfigImpl.h"
-
-REDFISH_PLATFORM_CONFIG_PRIVATE *mRedfishPlatformConfigPrivate =
NULL;
-
-/**
- Compare two value in HII statement format.
-
- @param[in] Value1 Firt value to compare.
- @param[in] Value2 Second value to be compared.
-
- @retval UINTN 0 is retuned when two values are equal.
- 1 is returned when first value is greater than second value.
- -1 is returned when second value is greater than first value.
-
-**/
-UINTN
-CompareHiiStatementValue (
- IN HII_STATEMENT_VALUE *Value1,
- IN HII_STATEMENT_VALUE *Value2
- )
-{
- INTN Result;
- UINT64 Data1;
- UINT64 Data2;
-
- if (Value1 == NULL || Value2 == NULL) {
- return 0xFF;
- }
-
- switch (Value1->Type) {
- case EFI_IFR_TYPE_NUM_SIZE_8:
- Data1 = Value1->Value.u8;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_16:
- Data1 = Value1->Value.u16;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_32:
- Data1 = Value1->Value.u32;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_64:
- Data1 = Value1->Value.u64;
- break;
- case EFI_IFR_TYPE_BOOLEAN:
- Data1 = (Value1->Value.b ? 1 : 0);
- break;
- default:
- return 0xFF;
- }
-
- switch (Value2->Type) {
- case EFI_IFR_TYPE_NUM_SIZE_8:
- Data2 = Value2->Value.u8;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_16:
- Data2 = Value2->Value.u16;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_32:
- Data2 = Value2->Value.u32;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_64:
- Data2 = Value2->Value.u64;
- break;
- case EFI_IFR_TYPE_BOOLEAN:
- Data2 = (Value2->Value.b ? 1 : 0);
- break;
- default:
- return 0xFF;
- }
-
- Result = (Data1 == Data2 ? 0 : (Data1 > Data2 ? 1 : -1));
-
- return Result;
-}
-
-/**
- Convert HII value to the string in HII one-of opcode.
-
- @param[in] Statement Statement private instance
-
- @retval EFI_STRING_ID The string ID in HII database.
- 0 is returned when something goes wrong.
-
-**/
-EFI_STRING_ID
-HiiValueToOneOfOptionStringId (
- IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement
- )
-{
- LIST_ENTRY *Link;
- HII_QUESTION_OPTION *Option;
-
- if (Statement->HiiStatement->Operand != EFI_IFR_ONE_OF_OP) {
- return 0;
- }
-
- if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
- return 0;
- }
-
- Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
- while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
- Option = HII_QUESTION_OPTION_FROM_LINK (Link);
-
- if (CompareHiiStatementValue (&Statement->HiiStatement->Value,
&Option->Value) == 0) {
- return Option->Text;
- }
-
- Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
- }
-
- return 0;
-}
-
-/**
- Convert HII string to the value in HII one-of opcode.
-
- @param[in] Statement Statement private instance
- @param[in] Schema Schema string
- @param[in] HiiString Input string
- @param[out] Value Value returned
-
- @retval EFI_SUCCESS HII value is returned successfully.
- @retval Others Errors occur
-
-**/
-EFI_STATUS
-HiiStringToOneOfOptionValue (
- IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement,
- IN CHAR8 *Schema,
- IN EFI_STRING HiiString,
- OUT HII_STATEMENT_VALUE *Value
- )
-{
- LIST_ENTRY *Link;
- HII_QUESTION_OPTION *Option;
- EFI_STRING TmpString;
- BOOLEAN Found;
-
- if (Statement == NULL || IS_EMPTY_STRING (HiiString) || Value == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (Statement->HiiStatement->Operand != EFI_IFR_ONE_OF_OP) {
- return EFI_UNSUPPORTED;
- }
-
- if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
- return EFI_NOT_FOUND;
- }
-
- Found = FALSE;
- Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
- while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
- Option = HII_QUESTION_OPTION_FROM_LINK (Link);
-
- TmpString = HiiGetRedfishString (Statement->ParentForm-
ParentFormset->HiiHandle, Schema, Option->Text);
- if (TmpString != NULL) {
- if (StrCmp (TmpString, HiiString) == 0) {
- CopyMem (Value, &Option->Value, sizeof (HII_STATEMENT_VALUE));
- Found = TRUE;
- }
- FreePool (TmpString);
- }
-
- if (Found) {
- return EFI_SUCCESS;
- }
-
- Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
- }
-
- return EFI_NOT_FOUND;
-}
-
-/**
- Convert HII value to numeric value in Redfish format.
-
- @param[in] Value Value to be converted.
- @param[out] RedfishValue Value in Redfish format.
-
- @retval EFI_SUCCESS Redfish value is returned successfully.
- @retval Others Errors occur
-
-**/
-EFI_STATUS
-HiiValueToRedfishNumeric (
- IN HII_STATEMENT_VALUE *Value,
- OUT EDKII_REDFISH_VALUE *RedfishValue
- )
-{
- if (Value == NULL || RedfishValue == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- switch (Value->Type) {
- case EFI_IFR_TYPE_NUM_SIZE_8:
- RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
- RedfishValue->Value.Integer = (INT64)Value->Value.u8;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_16:
- RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
- RedfishValue->Value.Integer = (INT64)Value->Value.u16;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_32:
- RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
- RedfishValue->Value.Integer = (INT64)Value->Value.u32;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_64:
- RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
- RedfishValue->Value.Integer = (INT64)Value->Value.u64;
- break;
- case EFI_IFR_TYPE_BOOLEAN:
- RedfishValue->Type = REDFISH_VALUE_TYPE_BOOLEAN;
- RedfishValue->Value.Boolean = Value->Value.b;
- break;
- default:
- RedfishValue->Type = REDFISH_VALUE_TYPE_UNKNOWN;
- break;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Convert numeric value in Redfish format to HII value.
-
- @param[in] RedfishValue Value in Redfish format to be converted.
- @param[out] Value HII value returned.
-
- @retval EFI_SUCCESS HII value is returned successfully.
- @retval Others Errors occur
-
-**/
-EFI_STATUS
-RedfishNumericToHiiValue (
- IN EDKII_REDFISH_VALUE *RedfishValue,
- OUT HII_STATEMENT_VALUE *Value
- )
-{
- if (Value == NULL || RedfishValue == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- switch (RedfishValue->Type) {
- case REDFISH_VALUE_TYPE_INTEGER:
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
- Value->Value.u64 = (UINT64)RedfishValue->Value.Integer;
- break;
- case REDFISH_VALUE_TYPE_BOOLEAN:
- Value->Type = EFI_IFR_TYPE_BOOLEAN;
- Value->Value.b = RedfishValue->Value.Boolean;
- break;
- default:
- Value->Type = EFI_IFR_TYPE_UNDEFINED;
- break;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Return the full Redfish schema string from the given Schema and Version.
-
- Returned schema string is: Schema + '.' + Version
-
- @param[in] Schema Schema string
- @param[in] Version Schema version string
-
- @retval CHAR8 * Schema string. NULL when errors occur.
-
-**/
-CHAR8 *
-GetFullSchemaString (
- IN CHAR8 *Schema,
- IN CHAR8 *Version
- )
-{
- UINTN Size;
- CHAR8 *FullName;
-
- if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version)) {
- return NULL;
- }
-
- Size = AsciiStrSize(CONFIGURE_LANGUAGE_PREFIX) + AsciiStrSize (Schema)
+ AsciiStrSize (Version);
-
- FullName = AllocatePool (Size);
- if (FullName == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, out-of-resource\n", __FUNCTION__));
- return NULL;
- }
-
- AsciiSPrint (FullName, Size, "%a%a.%a", CONFIGURE_LANGUAGE_PREFIX,
Schema, Version);
-
- return FullName;
-}
-
-/**
- Common implementation to get statement private instance.
-
- @param[in] RedfishPlatformConfigPrivate Private instance.
- @param[in] Schema Redfish schema string.
- @param[in] ConfigureLang Configure language that refers to this
statement.
- @param[out] Statement Statement instance
-
- @retval EFI_SUCCESS HII value is returned successfully.
- @retval Others Errors occur
-
-**/
-EFI_STATUS
-RedfishPlatformConfigGetStatementCommon (
- IN REDFISH_PLATFORM_CONFIG_PRIVATE
*RedfishPlatformConfigPrivate,
- IN CHAR8 *Schema,
- IN EFI_STRING ConfigureLang,
- OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE **Statement
- )
-{
- EFI_STATUS Status;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
-
- if (RedfishPlatformConfigPrivate == NULL || IS_EMPTY_STRING (Schema)
|| IS_EMPTY_STRING (ConfigureLang) || Statement == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- *Statement = NULL;
-
- Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
&RedfishPlatformConfigPrivate->PendingList);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
__FUNCTION__, Status));
- return Status;
- }
-
- TargetStatement = GetStatementPrivateByConfigureLang
(&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
- if (TargetStatement == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, No match HII statement is found by the
given %s in schema %a\n", __FUNCTION__, ConfigureLang, Schema));
- return EFI_NOT_FOUND;
- }
-
- //
- // Find current HII question value.
- //
- Status = GetQuestionValue (
- TargetStatement->ParentForm->ParentFormset->HiiFormSet,
- TargetStatement->ParentForm->HiiForm,
- TargetStatement->HiiStatement,
- GetSetValueWithHiiDriver
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to get question current value: %r\n",
__FUNCTION__, Status));
- return Status;
- }
-
-
- if (TargetStatement->HiiStatement->Value.Type ==
EFI_IFR_TYPE_UNDEFINED) {
- return EFI_DEVICE_ERROR;
- }
-
- //
- // Return Value.
- //
- *Statement = TargetStatement;
-
- return EFI_SUCCESS;
-}
-
-/**
- Get Redfish value with the given Schema and Configure Language.
-
- @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
- @param[in] Schema The Redfish schema to query.
- @param[in] Version The Redfish version to query.
- @param[in] ConfigureLang The target value which match this configure
Language.
- @param[out] Value The returned value.
-
- @retval EFI_SUCCESS Value is returned successfully.
- @retval Others Some error happened.
-
-**/
-EFI_STATUS
-EFIAPI
-RedfishPlatformConfigProtocolGetValue (
- IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
- IN CHAR8 *Schema,
- IN CHAR8 *Version,
- IN EFI_STRING ConfigureLang,
- OUT EDKII_REDFISH_VALUE *Value
- )
-{
- EFI_STATUS Status;
- REDFISH_PLATFORM_CONFIG_PRIVATE
*RedfishPlatformConfigPrivate;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
- EFI_STRING_ID StringId;
- CHAR8 *FullSchema;
- EFI_STRING HiiString;
- UINTN Size;
-
- if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
(Version) || IS_EMPTY_STRING (ConfigureLang) || Value == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- RedfishPlatformConfigPrivate =
REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
- Value->Type = REDFISH_VALUE_TYPE_UNKNOWN;
- FullSchema = NULL;
- HiiString = NULL;
-
- FullSchema = GetFullSchemaString (Schema, Version);
- if (FullSchema == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Status = RedfishPlatformConfigGetStatementCommon
(RedfishPlatformConfigPrivate, FullSchema, ConfigureLang,
&TargetStatement);
- if (EFI_ERROR (Status)) {
- goto RELEASE_RESOURCE;
- }
-
- switch (TargetStatement->HiiStatement->Operand) {
- case EFI_IFR_ONE_OF_OP:
- StringId = HiiValueToOneOfOptionStringId (TargetStatement);
- if (StringId == 0) {
- ASSERT (FALSE);
- Status = EFI_DEVICE_ERROR;
- goto RELEASE_RESOURCE;
- }
-
- HiiString = HiiGetRedfishString (TargetStatement->ParentForm-
ParentFormset->HiiHandle, FullSchema, StringId);
- if (HiiString == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, Can not find string ID: 0x%x with %a\n",
__FUNCTION__, StringId, FullSchema));
- Status = EFI_NOT_FOUND;
- goto RELEASE_RESOURCE;
- }
-
- Size = StrLen (HiiString) + 1;
- Value->Value.Buffer = AllocatePool (Size);
- if (Value->Value.Buffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto RELEASE_RESOURCE;
- }
-
- UnicodeStrToAsciiStrS (HiiString, Value->Value.Buffer, Size);
- Value->Type = REDFISH_VALUE_TYPE_STRING;
-
- break;
- case EFI_IFR_STRING_OP:
- if (TargetStatement->HiiStatement->Value.Type !=
EFI_IFR_TYPE_STRING) {
- ASSERT (FALSE);
- Status = EFI_DEVICE_ERROR;
- goto RELEASE_RESOURCE;
- }
-
- Value->Type = REDFISH_VALUE_TYPE_STRING;
- Value->Value.Buffer = AllocateCopyPool (StrSize ((CHAR16
*)TargetStatement->HiiStatement->Value.Buffer), TargetStatement-
HiiStatement->Value.Buffer);
- if (Value->Value.Buffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto RELEASE_RESOURCE;
- }
- break;
- case EFI_IFR_CHECKBOX_OP:
- case EFI_IFR_NUMERIC_OP:
- Status = HiiValueToRedfishNumeric (&TargetStatement->HiiStatement-
Value, Value);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to convert HII value to Redfish
value: %r\n", __FUNCTION__, Status));
- goto RELEASE_RESOURCE;
- }
- break;
- default:
- DEBUG ((DEBUG_ERROR, "%a, catch unsupported type: 0x%x! Please
contact with author if we need to support this type.\n", __FUNCTION__,
TargetStatement->HiiStatement->Operand));
- ASSERT (FALSE);
- Status = EFI_UNSUPPORTED;
- goto RELEASE_RESOURCE;
- }
-
-RELEASE_RESOURCE:
-
- if (FullSchema != NULL) {
- FreePool (FullSchema);
- }
-
- if (HiiString != NULL) {
- FreePool (HiiString);
- }
-
- return Status;
-}
-
-/**
- Function to save question value into HII database.
-
- @param[in] HiiFormset HII form-set instance
- @param[in] HiiForm HII form instance
- @param[in] HiiStatement HII statement that keeps new value.
- @param[in] Value New value to applyu.
-
- @retval EFI_SUCCESS HII value is returned successfully.
- @retval Others Errors occur
-
-**/
-EFI_STATUS
-RedfishPlatformConfigSaveQuestionValue (
- IN HII_FORMSET *HiiFormset,
- IN HII_FORM *HiiForm,
- IN HII_STATEMENT *HiiStatement,
- IN HII_STATEMENT_VALUE *Value
- )
-{
- EFI_STATUS Status;
-
- if (HiiFormset == NULL || HiiForm == NULL || HiiStatement == NULL ||
Value == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- Status = SetQuestionValue (
- HiiFormset,
- HiiForm,
- HiiStatement,
- Value
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to set question value: %r\n",
__FUNCTION__, Status));
- return Status;
- }
-
- Status = SubmitForm (HiiFormset, HiiForm);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to submit form: %r\n",
__FUNCTION__, Status));
- return Status;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Common implementation to set statement private instance.
-
- @param[in] RedfishPlatformConfigPrivate Private instance.
- @param[in] Schema Redfish schema string.
- @param[in] ConfigureLang Configure language that refers to this
statement.
- @param[in] Statement Statement instance
-
- @retval EFI_SUCCESS HII value is returned successfully.
- @retval Others Errors occur
-
-**/
-EFI_STATUS
-RedfishPlatformConfigSetStatementCommon (
- IN REDFISH_PLATFORM_CONFIG_PRIVATE
*RedfishPlatformConfigPrivate,
- IN CHAR8 *Schema,
- IN EFI_STRING ConfigureLang,
- IN HII_STATEMENT_VALUE *StatementValue
- )
-{
- EFI_STATUS Status;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
- EFI_STRING TempBuffer;
-
- if (RedfishPlatformConfigPrivate == NULL || IS_EMPTY_STRING (Schema)
|| IS_EMPTY_STRING (ConfigureLang) || StatementValue == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- TempBuffer = NULL;
-
- Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
&RedfishPlatformConfigPrivate->PendingList);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
__FUNCTION__, Status));
- return Status;
- }
-
- TargetStatement = GetStatementPrivateByConfigureLang
(&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
- if (TargetStatement == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, No match HII statement is found by the
given %s in schema %a\n", __FUNCTION__, ConfigureLang, Schema));
- return EFI_NOT_FOUND;
- }
-
- if (StatementValue->Type != TargetStatement->HiiStatement->Value.Type)
{
- //
- // We treat one-of type as string in Redfish. But one-of statement is not
- // in string format from HII point of view. Do a patch here.
- //
- if (TargetStatement->HiiStatement->Operand == EFI_IFR_ONE_OF_OP
&& StatementValue->Type == EFI_IFR_TYPE_STRING) {
- TempBuffer = AllocatePool (StatementValue->BufferLen * sizeof
(CHAR16));
- if (TempBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- AsciiStrToUnicodeStrS (StatementValue->Buffer, TempBuffer,
StatementValue->BufferLen);
- FreePool (StatementValue->Buffer);
- StatementValue->Buffer = NULL;
- StatementValue->BufferLen = 0;
-
- Status = HiiStringToOneOfOptionValue (TargetStatement, Schema,
TempBuffer, StatementValue);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to find option value by the given
%s\n", __FUNCTION__, TempBuffer));
- FreePool (TempBuffer);
- return EFI_NOT_FOUND;
- }
-
- FreePool (TempBuffer);
- } else if (TargetStatement->HiiStatement->Operand ==
EFI_IFR_NUMERIC_OP && StatementValue->Type ==
EFI_IFR_TYPE_NUM_SIZE_64) {
- //
- // Redfish only has numeric value type and it does not care about the
value size.
- // Do a patch here so we have proper value size applied.
- //
- StatementValue->Type = TargetStatement->HiiStatement->Value.Type;
- } else {
- DEBUG ((DEBUG_ERROR, "%a, catch value type mismatch! input type:
0x%x but target value type: 0x%x\n", __FUNCTION__, StatementValue-
Type, TargetStatement->HiiStatement->Value.Type));
- ASSERT (FALSE);
- }
- }
-
- Status = RedfishPlatformConfigSaveQuestionValue (
- TargetStatement->ParentForm->ParentFormset->HiiFormSet,
- TargetStatement->ParentForm->HiiForm,
- TargetStatement->HiiStatement,
- StatementValue
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to save question value: %r\n",
__FUNCTION__, Status));
- return Status;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Set Redfish value with the given Schema and Configure Language.
-
- @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
- @param[in] Schema The Redfish schema to query.
- @param[in] Version The Redfish version to query.
- @param[in] ConfigureLang The target value which match this configure
Language.
- @param[in] Value The value to set.
-
- @retval EFI_SUCCESS Value is returned successfully.
- @retval Others Some error happened.
-
-**/
-EFI_STATUS
-EFIAPI
-RedfishPlatformConfigProtocolSetValue (
- IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
- IN CHAR8 *Schema,
- IN CHAR8 *Version,
- IN EFI_STRING ConfigureLang,
- IN EDKII_REDFISH_VALUE Value
- )
-{
- EFI_STATUS Status;
- REDFISH_PLATFORM_CONFIG_PRIVATE
*RedfishPlatformConfigPrivate;
- CHAR8 *FullSchema;
- HII_STATEMENT_VALUE NewValue;
-
- if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
(Version) || IS_EMPTY_STRING (ConfigureLang)) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (Value.Type == REDFISH_VALUE_TYPE_UNKNOWN || Value.Type >=
REDFISH_VALUE_TYPE_MAX) {
- return EFI_INVALID_PARAMETER;
- }
-
- RedfishPlatformConfigPrivate =
REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
- FullSchema = NULL;
-
- FullSchema = GetFullSchemaString (Schema, Version);
- if (FullSchema == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- ZeroMem (&NewValue, sizeof (HII_STATEMENT_VALUE));
-
- switch (Value.Type) {
- case REDFISH_VALUE_TYPE_INTEGER:
- case REDFISH_VALUE_TYPE_BOOLEAN:
- Status = RedfishNumericToHiiValue (&Value, &NewValue);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to convert Redfish value to Hii
value: %r\n", __FUNCTION__, Status));
- goto RELEASE_RESOURCE;
- }
- break;
- case REDFISH_VALUE_TYPE_STRING:
- NewValue.Type = EFI_IFR_TYPE_STRING;
- NewValue.BufferLen = (UINT16)AsciiStrSize (Value.Value.Buffer);
- NewValue.Buffer = AllocateCopyPool (NewValue.BufferLen,
Value.Value.Buffer);
- if (NewValue.Buffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto RELEASE_RESOURCE;
- }
- break;
- default:
- ASSERT (FALSE);
- break;
- }
-
- Status = RedfishPlatformConfigSetStatementCommon
(RedfishPlatformConfigPrivate, FullSchema, ConfigureLang, &NewValue);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to set value to statement: %r\n",
__FUNCTION__, Status));
- }
-
-RELEASE_RESOURCE:
-
- if (FullSchema != NULL) {
- FreePool (FullSchema);
- }
-
- return Status;
-}
-
-/**
- Get the list of Configure Language from platform configuration by the given
Schema and Pattern.
-
- @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
- @param[in] Schema The Redfish schema to query.
- @param[in] Version The Redfish version to query.
- @param[in] Pattern The target Configure Language pattern.
- @param[out] ConfigureLangList The list of Configure Language.
- @param[out] Count The number of Configure Language in
ConfigureLangList.
-
- @retval EFI_SUCCESS ConfigureLangList is returned successfully.
- @retval Others Some error happened.
-
-**/
-EFI_STATUS
-EFIAPI
-RedfishPlatformConfigProtocolGetConfigureLang (
- IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
- IN CHAR8 *Schema,
- IN CHAR8 *Version,
- IN EFI_STRING Pattern,
- OUT EFI_STRING **ConfigureLangList,
- OUT UINTN *Count
- )
-{
- REDFISH_PLATFORM_CONFIG_PRIVATE
*RedfishPlatformConfigPrivate;
- EFI_STATUS Status;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST StatementList;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF *StatementRef;
- LIST_ENTRY *NextLink;
- EFI_STRING TmpString;
- EFI_STRING *TmpConfigureLangList;
- UINTN Index;
- CHAR8 *FullSchema;
-
- if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
(Version) || Count == NULL || ConfigureLangList == NULL ||
IS_EMPTY_STRING (Pattern)) {
- return EFI_INVALID_PARAMETER;
- }
-
- *Count = 0;
- *ConfigureLangList = NULL;
- FullSchema = NULL;
- RedfishPlatformConfigPrivate =
REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
-
- Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
&RedfishPlatformConfigPrivate->PendingList);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
__FUNCTION__, Status));
- return Status;
- }
-
- FullSchema = GetFullSchemaString (Schema, Version);
- if (FullSchema == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Status = GetStatementPrivateByConfigureLangRegex (
- RedfishPlatformConfigPrivate->RegularExpressionProtocol,
- &RedfishPlatformConfigPrivate->FormsetList,
- FullSchema,
- Pattern,
- &StatementList
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a,
GetStatementPrivateByConfigureLangRegex failure: %r\n", __FUNCTION__,
Status));
- goto RELEASE_RESOURCE;
- }
-
- if (!IsListEmpty (&StatementList.StatementList)) {
-
- TmpConfigureLangList = AllocateZeroPool (sizeof (CHAR16 *) *
StatementList.Count);
- if (TmpConfigureLangList == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto RELEASE_RESOURCE;
- }
-
- Index = 0;
- NextLink = GetFirstNode (&StatementList.StatementList);
- while (!IsNull (&StatementList.StatementList, NextLink)) {
- StatementRef =
REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
- NextLink = GetNextNode (&StatementList.StatementList, NextLink);
-
- ASSERT (StatementRef->Statement->Description != 0);
- if (StatementRef->Statement->Description != 0) {
- TmpString = HiiGetRedfishString (StatementRef->Statement-
ParentForm->ParentFormset->HiiHandle, FullSchema, StatementRef-
Statement->Description);
- ASSERT (TmpString != NULL);
- if (TmpString != NULL) {
- TmpConfigureLangList[Index] = AllocateCopyPool (StrSize (TmpString),
TmpString);
- ASSERT (TmpConfigureLangList[Index] != NULL);
- FreePool (TmpString);
- ++Index;
- }
- }
- }
- }
-
- *Count = StatementList.Count;
- *ConfigureLangList = TmpConfigureLangList;
-
-RELEASE_RESOURCE:
-
- if (FullSchema != NULL) {
- FreePool (FullSchema);
- }
-
- ReleaseStatementList (&StatementList);
-
- return Status;
-}
-
-
-/**
- Get the list of supported Redfish schema from paltform configuration on
give HII handle.
-
- @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
- @param[in] HiiHandle The target handle to search. If handle is NULL,
- this function return all schema from HII database.
- @param[out] SupportedSchema The supported schema list which is
separated by ';'.
- The SupportedSchema is allocated by the callee. It's caller's
- responsibility to free this buffer using FreePool().
-
- @retval EFI_SUCCESS Schema is returned successfully.
- @retval Others Some error happened.
-
-**/
-EFI_STATUS
-EFIAPI
-RedfishPlatformConfigProtocolGetSupportedSchema (
- IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
- IN EFI_HII_HANDLE HiiHandle, OPTIONAL
- OUT CHAR8 **SupportedSchema
- )
-{
- REDFISH_PLATFORM_CONFIG_PRIVATE
*RedfishPlatformConfigPrivate;
- EFI_STATUS Status;
- LIST_ENTRY *HiiFormsetLink;
- LIST_ENTRY *HiiFormsetNextLink;
- REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
- UINTN Index;
- UINTN StringSize;
- CHAR8 *StringBuffer;
- UINTN StringIndex;
-
- if (This == NULL || SupportedSchema == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- *SupportedSchema = NULL;
-
- RedfishPlatformConfigPrivate =
REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
-
- Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
&RedfishPlatformConfigPrivate->PendingList);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
__FUNCTION__, Status));
- return Status;
- }
-
- if (IsListEmpty (&RedfishPlatformConfigPrivate->FormsetList)) {
- return EFI_NOT_FOUND;
- }
-
- //
- // Calculate for string buffer size.
- //
- StringSize = 0;
- HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate-
FormsetList);
- while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList,
HiiFormsetLink)) {
- HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate-
FormsetList, HiiFormsetLink);
- HiiFormsetPrivate =
REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
- if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
- HiiFormsetLink = HiiFormsetNextLink;
- continue;
- }
-
- if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
- for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count;
Index++) {
- StringSize += AsciiStrSize (HiiFormsetPrivate-
SupportedSchema.SchemaList[Index]);
- }
- }
-
- HiiFormsetLink = HiiFormsetNextLink;
- }
-
- if (StringSize == 0) {
- return EFI_NOT_FOUND;
- }
-
- StringBuffer = AllocatePool (StringSize);
- if (StringBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- StringIndex = 0;
- HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate-
FormsetList);
- while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList,
HiiFormsetLink)) {
- HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate-
FormsetList, HiiFormsetLink);
- HiiFormsetPrivate =
REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
- if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
- HiiFormsetLink = HiiFormsetNextLink;
- continue;
- }
-
- if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
- for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count;
Index++) {
- AsciiStrCpyS (&StringBuffer[StringIndex], (StringSize - StringIndex),
HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
- StringIndex += AsciiStrLen (HiiFormsetPrivate-
SupportedSchema.SchemaList[Index]);
- StringBuffer[StringIndex] = ';';
- ++StringIndex;
- }
- }
-
- HiiFormsetLink = HiiFormsetNextLink;
- }
-
- StringBuffer[--StringIndex] = '\0';
-
- *SupportedSchema = StringBuffer;
-
- return EFI_SUCCESS;
-}
-
-/**
- Functions which are registered to receive notification of
- database events have this prototype. The actual event is encoded
- in NotifyType. The following table describes how PackageType,
- PackageGuid, Handle, and Package are used for each of the
- notification types.
-
- @param[in] PackageType Package type of the notification.
- @param[in] PackageGuid If PackageType is
- EFI_HII_PACKAGE_TYPE_GUID, then this is
- the pointer to the GUID from the Guid
- field of EFI_HII_PACKAGE_GUID_HEADER.
- Otherwise, it must be NULL.
- @param[in] Package Points to the package referred to by the
- notification Handle The handle of the package
- list which contains the specified package.
- @param[in] Handle The HII handle.
- @param[in] NotifyType The type of change concerning the
- database. See
- EFI_HII_DATABASE_NOTIFY_TYPE.
-
-**/
-EFI_STATUS
-EFIAPI
-RedfishPlatformConfigFormUpdateNotify (
- IN UINT8 PackageType,
- IN CONST EFI_GUID *PackageGuid,
- IN CONST EFI_HII_PACKAGE_HEADER *Package,
- IN EFI_HII_HANDLE Handle,
- IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
- )
-{
- EFI_STATUS Status;
-
- if (NotifyType == EFI_HII_DATABASE_NOTIFY_NEW_PACK || NotifyType
== EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
- //
- // HII formset on this handle is updated by driver during run-time. The
formset needs to be reloaded.
- //
- Status = NotifyFormsetUpdate (Handle, &mRedfishPlatformConfigPrivate-
PendingList);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to notify updated formset of HII
handle: 0x%x\n", __FUNCTION__, Handle));
- return Status;
- }
- } else if (NotifyType == EFI_HII_DATABASE_NOTIFY_REMOVE_PACK) {
- //
- // HII resource is removed. The formset is no longer exist.
- //
- Status = NotifyFormsetDeleted (Handle,
&mRedfishPlatformConfigPrivate->PendingList);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to notify deleted formset of HII
handle: 0x%x\n", __FUNCTION__, Handle));
- return Status;
- }
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- This is a EFI_HII_STRING_PROTOCOL notification event handler.
-
- Install HII package notification.
-
- @param[in] Event Event whose notification function is being invoked.
- @param[in] Context Pointer to the notification function's context.
-
-**/
-VOID
-EFIAPI
-HiiStringProtocolInstalled (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-{
- EFI_STATUS Status;
-
- //
- // Locate HII database protocol.
- //
- Status = gBS->LocateProtocol (
- &gEfiHiiStringProtocolGuid,
- NULL,
- (VOID **)&mRedfishPlatformConfigPrivate->HiiString
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, locate EFI_HII_STRING_PROTOCOL failure:
%r\n", __FUNCTION__, Status));
- return;
- }
-
- gBS->CloseEvent (Event);
- mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent = NULL;
-}
-
-/**
- This is a EFI_HII_DATABASE_PROTOCOL notification event handler.
-
- Install HII package notification.
-
- @param[in] Event Event whose notification function is being invoked.
- @param[in] Context Pointer to the notification function's context.
-
-**/
-VOID
-EFIAPI
-HiiDatabaseProtocolInstalled (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-{
- EFI_STATUS Status;
-
- //
- // Locate HII database protocol.
- //
- Status = gBS->LocateProtocol (
- &gEfiHiiDatabaseProtocolGuid,
- NULL,
- (VOID **)&mRedfishPlatformConfigPrivate->HiiDatabase
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, locate EFI_HII_DATABASE_PROTOCOL
failure: %r\n", __FUNCTION__, Status));
- return;
- }
-
- //
- // Register package notification when new form package is installed.
- //
- Status = mRedfishPlatformConfigPrivate->HiiDatabase-
RegisterPackageNotify (
- mRedfishPlatformConfigPrivate->HiiDatabase,
- EFI_HII_PACKAGE_FORMS,
- NULL,
- RedfishPlatformConfigFormUpdateNotify,
- EFI_HII_DATABASE_NOTIFY_NEW_PACK,
- &mRedfishPlatformConfigPrivate->NotifyHandle
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for
EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__,
Status));
- }
-
- //
- // Register package notification when new form package is updated.
- //
- Status = mRedfishPlatformConfigPrivate->HiiDatabase-
RegisterPackageNotify (
- mRedfishPlatformConfigPrivate->HiiDatabase,
- EFI_HII_PACKAGE_FORMS,
- NULL,
- RedfishPlatformConfigFormUpdateNotify,
- EFI_HII_DATABASE_NOTIFY_ADD_PACK,
- &mRedfishPlatformConfigPrivate->NotifyHandle
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for
EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__,
Status));
- }
-
-#if REDFISH_PLATFORM_CONFIG_DELETE_EXPIRED_FORMSET
- //
- // Register package notification when new form package is removed.
- //
- Status = mRedfishPlatformConfigPrivate->HiiDatabase-
RegisterPackageNotify (
- mRedfishPlatformConfigPrivate->HiiDatabase,
- EFI_HII_PACKAGE_FORMS,
- NULL,
- RedfishPlatformConfigFormUpdateNotify,
- EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
- &mRedfishPlatformConfigPrivate->NotifyHandle
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for
EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__,
Status));
- }
-#endif
-
- gBS->CloseEvent (Event);
- mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent = NULL;
-
-}
-
-/**
- This is a EFI_REGULAR_EXPRESSION_PROTOCOL notification event handler.
-
- @param[in] Event Event whose notification function is being invoked.
- @param[in] Context Pointer to the notification function's context.
-
-**/
-VOID
-EFIAPI
-RegexProtocolInstalled (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-{
- EFI_STATUS Status;
-
- //
- // Locate regular expression protocol.
- //
- Status = gBS->LocateProtocol (
- &gEfiRegularExpressionProtocolGuid,
- NULL,
- (VOID **)&mRedfishPlatformConfigPrivate-
RegularExpressionProtocol
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, locate
EFI_REGULAR_EXPRESSION_PROTOCOL failure: %r\n", __FUNCTION__,
Status));
- return;
- }
-
- gBS->CloseEvent (Event);
- mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent = NULL;
-
-}
-
-/**
- Unloads an image.
-
- @param ImageHandle Handle that identifies the image to be
unloaded.
-
- @retval EFI_SUCCESS The image has been unloaded.
- @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
-
-**/
-EFI_STATUS
-EFIAPI
-RedfishPlatformConfigDxeUnload (
- IN EFI_HANDLE ImageHandle
- )
-{
- EFI_STATUS Status;
-
- if (mRedfishPlatformConfigPrivate != NULL) {
- Status = gBS->UninstallProtocolInterface (
- mRedfishPlatformConfigPrivate->ImageHandle,
- &gEdkIIRedfishPlatformConfigProtocolGuid,
- (VOID*)&mRedfishPlatformConfigPrivate->Protocol
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, can not uninstall
gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
- ASSERT (FALSE);
- }
-
- //
- // Close events
- //
- if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent != NULL) {
- gBS->CloseEvent (mRedfishPlatformConfigPrivate-
HiiDbNotify.ProtocolEvent);
- }
- if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent != NULL)
{
- gBS->CloseEvent (mRedfishPlatformConfigPrivate-
HiiStringNotify.ProtocolEvent);
- }
- if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent != NULL) {
- gBS->CloseEvent (mRedfishPlatformConfigPrivate-
RegexNotify.ProtocolEvent);
- }
-
- //
- // Unregister package notification.
- //
- if (mRedfishPlatformConfigPrivate->NotifyHandle != NULL) {
- mRedfishPlatformConfigPrivate->HiiDatabase->UnregisterPackageNotify
(
- mRedfishPlatformConfigPrivate->HiiDatabase,
- mRedfishPlatformConfigPrivate->NotifyHandle
- );
- }
-
- ReleaseFormsetList (&mRedfishPlatformConfigPrivate->FormsetList);
- FreePool (mRedfishPlatformConfigPrivate);
- mRedfishPlatformConfigPrivate = NULL;
- }
-
- return EFI_SUCCESS;
-}
-
-
-/**
- This is the declaration of an EFI image entry point. This entry point is
- the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
- both device drivers and bus drivers.
-
- @param ImageHandle The firmware allocated handle for the UEFI
image.
- @param SystemTable A pointer to the EFI System Table.
-
- @retval EFI_SUCCESS The operation completed successfully.
- @retval Others An unexpected error occurred.
-**/
-EFI_STATUS
-EFIAPI
-RedfishPlatformConfigDxeEntryPoint (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
-
- mRedfishPlatformConfigPrivate = (REDFISH_PLATFORM_CONFIG_PRIVATE
*)AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PRIVATE));
- if (mRedfishPlatformConfigPrivate == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, can not allocate pool for
REDFISH_PLATFORM_CONFIG_PRIVATE\n", __FUNCTION__));
- ASSERT (FALSE);
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Protocol initialization
- //
- mRedfishPlatformConfigPrivate->ImageHandle = ImageHandle;
- mRedfishPlatformConfigPrivate->Protocol.GetValue =
RedfishPlatformConfigProtocolGetValue;
- mRedfishPlatformConfigPrivate->Protocol.SetValue =
RedfishPlatformConfigProtocolSetValue;
- mRedfishPlatformConfigPrivate->Protocol.GetConfigureLang =
RedfishPlatformConfigProtocolGetConfigureLang;
- mRedfishPlatformConfigPrivate->Protocol.GetSupportedSchema =
RedfishPlatformConfigProtocolGetSupportedSchema;
-
- InitializeListHead (&mRedfishPlatformConfigPrivate->FormsetList);
- InitializeListHead (&mRedfishPlatformConfigPrivate->PendingList);
-
- Status = gBS->InstallProtocolInterface (
- &ImageHandle,
- &gEdkIIRedfishPlatformConfigProtocolGuid,
- EFI_NATIVE_INTERFACE,
- (VOID*)&mRedfishPlatformConfigPrivate->Protocol
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, can not install
gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
- ASSERT (FALSE);
- }
-
- //
- // Install protocol notification if HII database protocol is installed.
- //
- mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent =
EfiCreateProtocolNotifyEvent (
- &gEfiHiiDatabaseProtocolGuid,
- TPL_CALLBACK,
- HiiDatabaseProtocolInstalled,
- NULL,
- &mRedfishPlatformConfigPrivate-
HiiDbNotify.Registration
- );
- if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
gEfiHiiDatabaseProtocolGuid\n", __FUNCTION__));
- ASSERT (FALSE);
- }
-
- //
- // Install protocol notification if HII string protocol is installed.
- //
- mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent =
EfiCreateProtocolNotifyEvent (
- &gEfiHiiStringProtocolGuid,
- TPL_CALLBACK,
- HiiStringProtocolInstalled,
- NULL,
- &mRedfishPlatformConfigPrivate-
HiiStringNotify.Registration
- );
- if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent == NULL)
{
- DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
gEfiHiiStringProtocolGuid\n", __FUNCTION__));
- ASSERT (FALSE);
- }
-
- //
- // Install protocol notification if regular expression protocol is installed.
- //
- mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent =
EfiCreateProtocolNotifyEvent (
- &gEfiRegularExpressionProtocolGuid,
- TPL_CALLBACK,
- RegexProtocolInstalled,
- NULL,
- &mRedfishPlatformConfigPrivate-
RegexNotify.Registration
- );
- if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
gEfiRegularExpressionProtocolGuid\n", __FUNCTION__));
- ASSERT (FALSE);
- }
-
- return EFI_SUCCESS;
-}
+/** @file
+
+ The implementation of EDKII Redfidh Platform Config Protocol.
+
+ (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "RedfishPlatformConfigDxe.h"
+#include "RedfishPlatformConfigImpl.h"
+
+REDFISH_PLATFORM_CONFIG_PRIVATE *mRedfishPlatformConfigPrivate =
NULL;
+
+
+/**
+ Zero extend integer/boolean to UINT64 for comparing.
+
+ @param Value HII Value to be converted.
+
+**/
+UINT64
+ExtendHiiValueToU64 (
+ IN HII_STATEMENT_VALUE *Value
+ )
+{
+ UINT64 Temp;
+
+ Temp = 0;
+ switch (Value->Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ Temp = Value->Value.u8;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ Temp = Value->Value.u16;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ Temp = Value->Value.u32;
+ break;
+
+ case EFI_IFR_TYPE_BOOLEAN:
+ Temp = Value->Value.b;
+ break;
+
+ case EFI_IFR_TYPE_TIME:
+ case EFI_IFR_TYPE_DATE:
+ default:
+ break;
+ }
+
+ return Temp;
+}
+
+/**
+ Set value of a data element in an Array by its Index in ordered list buffer.
+
+ @param Array The data array.
+ @param Type Type of the data in this array.
+ @param Index Zero based index for data in this array.
+ @param Value The value to be set.
+
+**/
+VOID
+OrderedListSetArrayData (
+ IN VOID *Array,
+ IN UINT8 Type,
+ IN UINTN Index,
+ IN UINT64 Value
+ )
+{
+
+ ASSERT (Array != NULL);
+
+ switch (Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ *(((UINT8 *) Array) + Index) = (UINT8) Value;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ *(((UINT16 *) Array) + Index) = (UINT16) Value;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ *(((UINT32 *) Array) + Index) = (UINT32) Value;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ *(((UINT64 *) Array) + Index) = (UINT64) Value;
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ Return data element in an Array by its Index in ordered list array buffer.
+
+ @param Array The data array.
+ @param Type Type of the data in this array.
+ @param Index Zero based index for data in this array.
+
+ @retval Value The data to be returned
+
+**/
+UINT64
+OrderedListGetArrayData (
+ IN VOID *Array,
+ IN UINT8 Type,
+ IN UINTN Index
+ )
+{
+ UINT64 Data;
+
+ ASSERT (Array != NULL);
+
+ Data = 0;
+ switch (Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ Data = (UINT64) *(((UINT8 *) Array) + Index);
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ Data = (UINT64) *(((UINT16 *) Array) + Index);
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ Data = (UINT64) *(((UINT32 *) Array) + Index);
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ Data = (UINT64) *(((UINT64 *) Array) + Index);
+ break;
+
+ default:
+ break;
+ }
+
+ return Data;
+}
+
+/**
+ Find string ID of option if its value equals to given value.
+
+ @param[in] HiiStatement Statement to search.
+ @param[in] Value Target value.
+
+ @retval EFI_SUCCESS HII value is returned successfully.
+ @retval Others Errors occur
+
+**/
+EFI_STRING_ID
+OrderedListOptionValueToStringId (
+ IN HII_STATEMENT *HiiStatement,
+ IN UINT64 Value
+ )
+{
+ LIST_ENTRY *Link;
+ HII_QUESTION_OPTION *Option;
+ BOOLEAN Found;
+ UINT64 CurrentValue;
+
+ if (HiiStatement == NULL) {
+ return 0;
+ }
+
+ if (HiiStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
+ return 0;
+ }
+
+ if (IsListEmpty (&HiiStatement->OptionListHead)) {
+ return 0;
+ }
+
+ Found = FALSE;
+ Link = GetFirstNode (&HiiStatement->OptionListHead);
+ while (!IsNull (&HiiStatement->OptionListHead, Link)) {
+ Option = HII_QUESTION_OPTION_FROM_LINK (Link);
+
+ CurrentValue = ExtendHiiValueToU64 (&Option->Value);
+ if (Value == CurrentValue) {
+ return Option->Text;
+ }
+
+ Link = GetNextNode (&HiiStatement->OptionListHead, Link);
+ }
+
+ return 0;
+}
+
+/**
+ Compare two value in HII statement format.
+
+ @param[in] Value1 Firt value to compare.
+ @param[in] Value2 Second value to be compared.
+
+ @retval INTN 0 is retuned when two values are equal.
+ 1 is returned when first value is greater than second value.
+ -1 is returned when second value is greater than first value.
+
+**/
+INTN
+CompareHiiStatementValue (
+ IN HII_STATEMENT_VALUE *Value1,
+ IN HII_STATEMENT_VALUE *Value2
+ )
+{
+ INTN Result;
+ UINT64 Data1;
+ UINT64 Data2;
+
+ if (Value1 == NULL || Value2 == NULL) {
+ return -1;
+ }
+
+ switch (Value1->Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ Data1 = Value1->Value.u8;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ Data1 = Value1->Value.u16;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ Data1 = Value1->Value.u32;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ Data1 = Value1->Value.u64;
+ break;
+ case EFI_IFR_TYPE_BOOLEAN:
+ Data1 = (Value1->Value.b ? 1 : 0);
+ break;
+ default:
+ return -1;
+ }
+
+ switch (Value2->Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ Data2 = Value2->Value.u8;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ Data2 = Value2->Value.u16;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ Data2 = Value2->Value.u32;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ Data2 = Value2->Value.u64;
+ break;
+ case EFI_IFR_TYPE_BOOLEAN:
+ Data2 = (Value2->Value.b ? 1 : 0);
+ break;
+ default:
+ return -1;
+ }
+
+ Result = (Data1 == Data2 ? 0 : (Data1 > Data2 ? 1 : -1));
+
+ return Result;
+}
+
+/**
+ Convert HII value to the string in HII one-of opcode.
+
+ @param[in] Statement Statement private instance
+
+ @retval EFI_STRING_ID The string ID in HII database.
+ 0 is returned when something goes wrong.
+
+**/
+EFI_STRING_ID
+HiiValueToOneOfOptionStringId (
+ IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement
+ )
+{
+ LIST_ENTRY *Link;
+ HII_QUESTION_OPTION *Option;
+
+ if (Statement->HiiStatement->Operand != EFI_IFR_ONE_OF_OP) {
+ return 0;
+ }
+
+ if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
+ return 0;
+ }
+
+ Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
+ while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
+ Option = HII_QUESTION_OPTION_FROM_LINK (Link);
+
+ if (CompareHiiStatementValue (&Statement->HiiStatement->Value,
&Option->Value) == 0) {
+ return Option->Text;
+ }
+
+ Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
+ }
+
+ return 0;
+}
+
+/**
+ Convert HII string to the value in HII one-of opcode.
+
+ @param[in] Statement Statement private instance
+ @param[in] Schema Schema string
+ @param[in] HiiString Input string
+ @param[out] Value Value returned
+
+ @retval EFI_SUCCESS HII value is returned successfully.
+ @retval Others Errors occur
+
+**/
+EFI_STATUS
+HiiStringToOneOfOptionValue (
+ IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement,
+ IN CHAR8 *Schema,
+ IN EFI_STRING HiiString,
+ OUT HII_STATEMENT_VALUE *Value
+ )
+{
+ LIST_ENTRY *Link;
+ HII_QUESTION_OPTION *Option;
+ EFI_STRING TmpString;
+ BOOLEAN Found;
+
+ if (Statement == NULL || IS_EMPTY_STRING (HiiString) || Value == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Statement->HiiStatement->Operand != EFI_IFR_ONE_OF_OP) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
+ return EFI_NOT_FOUND;
+ }
+
+ Found = FALSE;
+ Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
+ while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
+ Option = HII_QUESTION_OPTION_FROM_LINK (Link);
+
+ TmpString = HiiGetRedfishString (Statement->ParentForm-
ParentFormset->HiiHandle, Schema, Option->Text);
+ if (TmpString != NULL) {
+ if (StrCmp (TmpString, HiiString) == 0) {
+ CopyMem (Value, &Option->Value, sizeof (HII_STATEMENT_VALUE));
+ Found = TRUE;
+ }
+ FreePool (TmpString);
+ }
+
+ if (Found) {
+ return EFI_SUCCESS;
+ }
+
+ Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Convert HII value to numeric value in Redfish format.
+
+ @param[in] Value Value to be converted.
+ @param[out] RedfishValue Value in Redfish format.
+
+ @retval EFI_SUCCESS Redfish value is returned successfully.
+ @retval Others Errors occur
+
+**/
+EFI_STATUS
+HiiValueToRedfishNumeric (
+ IN HII_STATEMENT_VALUE *Value,
+ OUT EDKII_REDFISH_VALUE *RedfishValue
+ )
+{
+ if (Value == NULL || RedfishValue == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ switch (Value->Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
+ RedfishValue->Value.Integer = (INT64)Value->Value.u8;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
+ RedfishValue->Value.Integer = (INT64)Value->Value.u16;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
+ RedfishValue->Value.Integer = (INT64)Value->Value.u32;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
+ RedfishValue->Value.Integer = (INT64)Value->Value.u64;
+ break;
+ case EFI_IFR_TYPE_BOOLEAN:
+ RedfishValue->Type = REDFISH_VALUE_TYPE_BOOLEAN;
+ RedfishValue->Value.Boolean = Value->Value.b;
+ break;
+ default:
+ RedfishValue->Type = REDFISH_VALUE_TYPE_UNKNOWN;
+ break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Convert numeric value in Redfish format to HII value.
+
+ @param[in] RedfishValue Value in Redfish format to be converted.
+ @param[out] Value HII value returned.
+
+ @retval EFI_SUCCESS HII value is returned successfully.
+ @retval Others Errors occur
+
+**/
+EFI_STATUS
+RedfishNumericToHiiValue (
+ IN EDKII_REDFISH_VALUE *RedfishValue,
+ OUT HII_STATEMENT_VALUE *Value
+ )
+{
+ if (Value == NULL || RedfishValue == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ switch (RedfishValue->Type) {
+ case REDFISH_VALUE_TYPE_INTEGER:
+ Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
+ Value->Value.u64 = (UINT64)RedfishValue->Value.Integer;
+ break;
+ case REDFISH_VALUE_TYPE_BOOLEAN:
+ Value->Type = EFI_IFR_TYPE_BOOLEAN;
+ Value->Value.b = RedfishValue->Value.Boolean;
+ break;
+ default:
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+ break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Dump the value in ordered list buffer.
+
+ @param[in] OrderedListStatement Ordered list statement.
+
+**/
+VOID
+DumpOrderedListValue (
+ IN HII_STATEMENT *OrderedListStatement
+ )
+{
+ UINT8 *Value8;
+ UINT16 *Value16;
+ UINT32 *Value32;
+ UINT64 *Value64;
+ UINTN Count;
+ UINTN Index;
+
+ if (OrderedListStatement == NULL || OrderedListStatement->Operand !=
EFI_IFR_ORDERED_LIST_OP) {
+ return;
+ }
+
+ DEBUG ((DEBUG_ERROR, "Value.Type= 0x%x\n", OrderedListStatement-
Value.Type));
+ DEBUG ((DEBUG_ERROR, "Value.BufferValueType= 0x%x\n",
OrderedListStatement->Value.BufferValueType));
+ DEBUG ((DEBUG_ERROR, "Value.BufferLen= 0x%x\n",
OrderedListStatement->Value.BufferLen));
+ DEBUG ((DEBUG_ERROR, "Value.Buffer= 0x%x\n", OrderedListStatement-
Value.Buffer));
+ DEBUG ((DEBUG_ERROR, "Value.MaxContainers= 0x%x\n",
OrderedListStatement->ExtraData.OrderListData.MaxContainers));
+ DEBUG ((DEBUG_ERROR, "StorageWidth= 0x%x\n",
OrderedListStatement->StorageWidth));
+
+ if (OrderedListStatement->Value.Buffer == NULL) {
+ return;
+ }
+
+ Value8 = NULL;
+ Value16 = NULL;
+ Value32 = NULL;
+ Value64 = NULL;
+ Count = 0;
+
+ switch (OrderedListStatement->Value.BufferValueType) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ Value8 = (UINT8 *)OrderedListStatement->Value.Buffer;
+ Count = OrderedListStatement->StorageWidth / sizeof (UINT8);
+ for (Index = 0; Index < Count; Index++) {
+ DEBUG ((DEBUG_ERROR, "%d ", Value8[Index]));
+ }
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ Value16 = (UINT16 *)OrderedListStatement->Value.Buffer;
+ Count = OrderedListStatement->StorageWidth / sizeof (UINT16);
+ for (Index = 0; Index < Count; Index++) {
+ DEBUG ((DEBUG_ERROR, "%d ", Value16[Index]));
+ }
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ Value32 = (UINT32 *)OrderedListStatement->Value.Buffer;
+ Count = OrderedListStatement->StorageWidth / sizeof (UINT32);
+ for (Index = 0; Index < Count; Index++) {
+ DEBUG ((DEBUG_ERROR, "%d ", Value32[Index]));
+ }
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ Value64 = (UINT64 *)OrderedListStatement->Value.Buffer;
+ Count = OrderedListStatement->StorageWidth / sizeof (UINT64);
+ for (Index = 0; Index < Count; Index++) {
+ DEBUG ((DEBUG_ERROR, "%d ", Value64[Index]));
+ }
+ break;
+ default:
+ Value8 = (UINT8 *)OrderedListStatement->Value.Buffer;
+ Count = OrderedListStatement->StorageWidth / sizeof (UINT8);
+ for (Index = 0; Index < Count; Index++) {
+ DEBUG ((DEBUG_ERROR, "%d ", Value8[Index]));
+ }
+ break;
+ }
+
+ DEBUG ((DEBUG_ERROR, "\n"));
+}
+
+/**
+ Convert HII value to the string in HII ordered list opcode. It's caller's
+ responsibility to free returned buffer using FreePool().
+
+ @param[in] Statement Statement private instance
+ @param[out] ReturnSize The size of returned array
+
+ @retval EFI_STRING_ID The string ID array for options in ordered list.
+
+**/
+EFI_STRING_ID *
+HiiValueToOrderedListOptionStringId (
+ IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement,
+ OUT UINTN *ReturnSize
+ )
+{
+ LIST_ENTRY *Link;
+ HII_QUESTION_OPTION *Option;
+ UINTN OptionCount;
+ EFI_STRING_ID *ReturnedArray;
+ UINTN Index;
+ UINT64 Value;
+
+ if (Statement == NULL || ReturnSize == NULL) {
+ return NULL;
+ }
+
+ *ReturnSize = 0;
+
+ if (Statement->HiiStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
+ return NULL;
+ }
+
+ if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
+ return NULL;
+ }
+
+ DEBUG_CODE (
+ DumpOrderedListValue (Statement->HiiStatement);
+ );
+
+ OptionCount = 0;
+ Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
+ while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
+ Option = HII_QUESTION_OPTION_FROM_LINK (Link);
+
+ ++OptionCount;
+
+ Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
+ }
+
+ *ReturnSize = OptionCount;
+ ReturnedArray = AllocatePool (sizeof (EFI_STRING_ID) * OptionCount);
+ if (ReturnedArray == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__));
+ *ReturnSize = 0;
+ return NULL;
+ }
+
+ for (Index = 0; Index < OptionCount; Index++) {
+ Value = OrderedListGetArrayData (Statement->HiiStatement-
Value.Buffer, Statement->HiiStatement->Value.BufferValueType, Index);
+ ReturnedArray[Index] = OrderedListOptionValueToStringId (Statement-
HiiStatement, Value);
+ }
+
+ return ReturnedArray;
+}
+
+/**
+ Convert HII string to the value in HII ordered list opcode.
+
+ @param[in] Statement Statement private instance
+ @param[in] Schema Schema string
+ @param[in] HiiString Input string
+ @param[out] Value Value returned
+
+ @retval EFI_SUCCESS HII value is returned successfully.
+ @retval Others Errors occur
+
+**/
+EFI_STATUS
+HiiStringToOrderedListOptionValue (
+ IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement,
+ IN CHAR8 *Schema,
+ IN EFI_STRING HiiString,
+ OUT UINT64 *Value
+ )
+{
+ LIST_ENTRY *Link;
+ HII_QUESTION_OPTION *Option;
+ EFI_STRING TmpString;
+ BOOLEAN Found;
+
+ if (Statement == NULL || IS_EMPTY_STRING (HiiString) || Value == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Value = 0;
+
+ if (Statement->HiiStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
+ return EFI_NOT_FOUND;
+ }
+
+ Found = FALSE;
+ Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
+ while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
+ Option = HII_QUESTION_OPTION_FROM_LINK (Link);
+
+ TmpString = HiiGetRedfishString (Statement->ParentForm-
ParentFormset->HiiHandle, Schema, Option->Text);
+ if (TmpString != NULL) {
+ if (StrCmp (TmpString, HiiString) == 0) {
+ *Value = ExtendHiiValueToU64 (&Option->Value);
+ Found = TRUE;
+ }
+ FreePool (TmpString);
+ }
+
+ if (Found) {
+ return EFI_SUCCESS;
+ }
+
+ Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Convert input ascii string to unicode string. It's caller's
+ responsibility to free returned buffer using FreePool().
+
+ @param[in] AsciiString Ascii string to be converted.
+
+ @retval CHAR16 * Unicode string on return.
+
+**/
+EFI_STRING
+StrToUnicodeStr (
+ IN CHAR8 *AsciiString
+ )
+{
+ UINTN StringLen;
+ EFI_STRING Buffer;
+ EFI_STATUS Status;
+
+ if (AsciiString == NULL || AsciiString[0] == '\0') {
+ return NULL;
+ }
+
+ StringLen = AsciiStrLen (AsciiString) + 1;
+ Buffer = AllocatePool (StringLen * sizeof (CHAR16));
+ if (Buffer == NULL) {
+ return NULL;
+ }
+
+ Status = AsciiStrToUnicodeStrS (AsciiString, Buffer, StringLen);
+ if (EFI_ERROR (Status)) {
+ FreePool (Buffer);
+ return NULL;
+ }
+
+ return Buffer;
+}
+
+/**
+ Return the full Redfish schema string from the given Schema and Version.
+
+ Returned schema string is: Schema + '.' + Version
+
+ @param[in] Schema Schema string
+ @param[in] Version Schema version string
+
+ @retval CHAR8 * Schema string. NULL when errors occur.
+
+**/
+CHAR8 *
+GetFullSchemaString (
+ IN CHAR8 *Schema,
+ IN CHAR8 *Version
+ )
+{
+ UINTN Size;
+ CHAR8 *FullName;
+
+ if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version)) {
+ return NULL;
+ }
+
+ Size = AsciiStrSize(CONFIGURE_LANGUAGE_PREFIX) + AsciiStrSize
(Schema) + AsciiStrSize (Version);
+
+ FullName = AllocatePool (Size);
+ if (FullName == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, out-of-resource\n", __FUNCTION__));
+ return NULL;
+ }
+
+ AsciiSPrint (FullName, Size, "%a%a.%a", CONFIGURE_LANGUAGE_PREFIX,
Schema, Version);
+
+ return FullName;
+}
+
+/**
+ Common implementation to get statement private instance.
+
+ @param[in] RedfishPlatformConfigPrivate Private instance.
+ @param[in] Schema Redfish schema string.
+ @param[in] ConfigureLang Configure language that refers to this
statement.
+ @param[out] Statement Statement instance
+
+ @retval EFI_SUCCESS HII value is returned successfully.
+ @retval Others Errors occur
+
+**/
+EFI_STATUS
+RedfishPlatformConfigGetStatementCommon (
+ IN REDFISH_PLATFORM_CONFIG_PRIVATE
*RedfishPlatformConfigPrivate,
+ IN CHAR8 *Schema,
+ IN EFI_STRING ConfigureLang,
+ OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE **Statement
+ )
+{
+ EFI_STATUS Status;
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
+
+ if (RedfishPlatformConfigPrivate == NULL || IS_EMPTY_STRING (Schema)
|| IS_EMPTY_STRING (ConfigureLang) || Statement == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Statement = NULL;
+
+ Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
&RedfishPlatformConfigPrivate->PendingList);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
__FUNCTION__, Status));
+ return Status;
+ }
+
+ TargetStatement = GetStatementPrivateByConfigureLang
(&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
+ if (TargetStatement == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, No match HII statement is found by the
given %s in schema %a\n", __FUNCTION__, ConfigureLang, Schema));
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Find current HII question value.
+ //
+ Status = GetQuestionValue (
+ TargetStatement->ParentForm->ParentFormset->HiiFormSet,
+ TargetStatement->ParentForm->HiiForm,
+ TargetStatement->HiiStatement,
+ GetSetValueWithHiiDriver
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to get question current value: %r\n",
__FUNCTION__, Status));
+ return Status;
+ }
+
+
+ if (TargetStatement->HiiStatement->Value.Type ==
EFI_IFR_TYPE_UNDEFINED) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Return Value.
+ //
+ *Statement = TargetStatement;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Get Redfish value with the given Schema and Configure Language.
+
+ @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+ @param[in] Schema The Redfish schema to query.
+ @param[in] Version The Redfish version to query.
+ @param[in] ConfigureLang The target value which match this configure
Language.
+ @param[out] Value The returned value.
+
+ @retval EFI_SUCCESS Value is returned successfully.
+ @retval Others Some error happened.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformConfigProtocolGetValue (
+ IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+ IN CHAR8 *Schema,
+ IN CHAR8 *Version,
+ IN EFI_STRING ConfigureLang,
+ OUT EDKII_REDFISH_VALUE *Value
+ )
+{
+ EFI_STATUS Status;
+ REDFISH_PLATFORM_CONFIG_PRIVATE
*RedfishPlatformConfigPrivate;
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
+ EFI_STRING_ID StringId;
+ EFI_STRING_ID *StringIdArray;
+ CHAR8 *FullSchema;
+ EFI_STRING HiiString;
+ UINTN Count;
+ UINTN Index;
+
+ if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
(Version) || IS_EMPTY_STRING (ConfigureLang) || Value == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ RedfishPlatformConfigPrivate =
REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
+ Value->Type = REDFISH_VALUE_TYPE_UNKNOWN;
+ Value->ArrayCount = 0;
+ Count = 0;
+ FullSchema = NULL;
+ HiiString = NULL;
+ StringIdArray = NULL;
+
+ FullSchema = GetFullSchemaString (Schema, Version);
+ if (FullSchema == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = RedfishPlatformConfigGetStatementCommon
(RedfishPlatformConfigPrivate, FullSchema, ConfigureLang,
&TargetStatement);
+ if (EFI_ERROR (Status)) {
+ goto RELEASE_RESOURCE;
+ }
+
+ switch (TargetStatement->HiiStatement->Operand) {
+ case EFI_IFR_ONE_OF_OP:
+ StringId = HiiValueToOneOfOptionStringId (TargetStatement);
+ if (StringId == 0) {
+ ASSERT (FALSE);
+ Status = EFI_DEVICE_ERROR;
+ goto RELEASE_RESOURCE;
+ }
+
+ Value->Value.Buffer = HiiGetRedfishAsciiString (TargetStatement-
ParentForm->ParentFormset->HiiHandle, FullSchema, StringId);
+ if (Value->Value.Buffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto RELEASE_RESOURCE;
+ }
+
+ Value->Type = REDFISH_VALUE_TYPE_STRING;
+ break;
+ case EFI_IFR_STRING_OP:
+ if (TargetStatement->HiiStatement->Value.Type !=
EFI_IFR_TYPE_STRING) {
+ ASSERT (FALSE);
+ Status = EFI_DEVICE_ERROR;
+ goto RELEASE_RESOURCE;
+ }
+
+ Value->Type = REDFISH_VALUE_TYPE_STRING;
+ Value->Value.Buffer = AllocatePool (StrLen ((CHAR16
*)TargetStatement->HiiStatement->Value.Buffer) + 1);
+ UnicodeStrToAsciiStrS ((CHAR16 *)TargetStatement->HiiStatement-
Value.Buffer, Value->Value.Buffer, StrLen ((CHAR16 *)TargetStatement-
HiiStatement->Value.Buffer) + 1);
+ break;
+ case EFI_IFR_CHECKBOX_OP:
+ case EFI_IFR_NUMERIC_OP:
+ Status = HiiValueToRedfishNumeric (&TargetStatement->HiiStatement-
Value, Value);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to convert HII value to Redfish
value: %r\n", __FUNCTION__, Status));
+ goto RELEASE_RESOURCE;
+ }
+ break;
+ case EFI_IFR_ACTION_OP:
+ if (TargetStatement->HiiStatement->Value.Type !=
EFI_IFR_TYPE_ACTION) {
+ ASSERT (FALSE);
+ Status = EFI_DEVICE_ERROR;
+ goto RELEASE_RESOURCE;
+ }
+
+ //
+ // Action has no value. Just return unknown type.
+ //
+ Value->Type = REDFISH_VALUE_TYPE_UNKNOWN;
+ break;
+ case EFI_IFR_ORDERED_LIST_OP:
+ StringIdArray = HiiValueToOrderedListOptionStringId (TargetStatement,
&Count);
+ if (StringIdArray == NULL) {
+ ASSERT (FALSE);
+ Status = EFI_DEVICE_ERROR;
+ goto RELEASE_RESOURCE;
+ }
+
+ Value->Value.StringArray = AllocatePool (sizeof (CHAR8 *) * Count);
+ if (Value->Value.StringArray == NULL) {
+ ASSERT (FALSE);
+ Status = EFI_OUT_OF_RESOURCES;
+ goto RELEASE_RESOURCE;
+ }
+
+ for (Index = 0; Index < Count; Index++) {
+ ASSERT (StringIdArray[Index] != 0);
+ Value->Value.StringArray[Index] = HiiGetRedfishAsciiString
(TargetStatement->ParentForm->ParentFormset->HiiHandle, FullSchema,
StringIdArray[Index]);
+ }
+
+ Value->ArrayCount = Count;
+ Value->Type = REDFISH_VALUE_TYPE_STRING_ARRAY;
+ break;
+ default:
+ DEBUG ((DEBUG_ERROR, "%a, catch unsupported type: 0x%x! Please
contact with author if we need to support this type.\n", __FUNCTION__,
TargetStatement->HiiStatement->Operand));
+ ASSERT (FALSE);
+ Status = EFI_UNSUPPORTED;
+ goto RELEASE_RESOURCE;
+ }
+
+RELEASE_RESOURCE:
+
+ if (FullSchema != NULL) {
+ FreePool (FullSchema);
+ }
+
+ if (HiiString != NULL) {
+ FreePool (HiiString);
+ }
+
+ if (StringIdArray != NULL) {
+ FreePool (StringIdArray);
+ }
+
+ return Status;
+}
+
+/**
+ Function to save question value into HII database.
+
+ @param[in] HiiFormset HII form-set instance
+ @param[in] HiiForm HII form instance
+ @param[in] HiiStatement HII statement that keeps new value.
+ @param[in] Value New value to applyu.
+
+ @retval EFI_SUCCESS HII value is returned successfully.
+ @retval Others Errors occur
+
+**/
+EFI_STATUS
+RedfishPlatformConfigSaveQuestionValue (
+ IN HII_FORMSET *HiiFormset,
+ IN HII_FORM *HiiForm,
+ IN HII_STATEMENT *HiiStatement,
+ IN HII_STATEMENT_VALUE *Value
+ )
+{
+ EFI_STATUS Status;
+
+ if (HiiFormset == NULL || HiiForm == NULL || HiiStatement == NULL ||
Value == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = SetQuestionValue (
+ HiiFormset,
+ HiiForm,
+ HiiStatement,
+ Value
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to set question value: %r\n",
__FUNCTION__, Status));
+ return Status;
+ }
+
+ Status = SubmitForm (HiiFormset, HiiForm);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to submit form: %r\n",
__FUNCTION__, Status));
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Common implementation to set statement private instance.
+
+ @param[in] RedfishPlatformConfigPrivate Private instance.
+ @param[in] Schema Redfish schema string.
+ @param[in] ConfigureLang Configure language that refers to this
statement.
+ @param[in] Statement Statement instance
+
+ @retval EFI_SUCCESS HII value is returned successfully.
+ @retval Others Errors occur
+
+**/
+EFI_STATUS
+RedfishPlatformConfigSetStatementCommon (
+ IN REDFISH_PLATFORM_CONFIG_PRIVATE
*RedfishPlatformConfigPrivate,
+ IN CHAR8 *Schema,
+ IN EFI_STRING ConfigureLang,
+ IN HII_STATEMENT_VALUE *StatementValue
+ )
+{
+ EFI_STATUS Status;
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
+ EFI_STRING TempBuffer;
+ UINT8 *StringArray;
+ UINTN Index;
+ UINT64 Value;
+ CHAR8 **CharArray;
+
+ if (RedfishPlatformConfigPrivate == NULL || IS_EMPTY_STRING (Schema)
|| IS_EMPTY_STRING (ConfigureLang) || StatementValue == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TempBuffer = NULL;
+ StringArray = NULL;
+
+ Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
&RedfishPlatformConfigPrivate->PendingList);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
__FUNCTION__, Status));
+ return Status;
+ }
+
+ TargetStatement = GetStatementPrivateByConfigureLang
(&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
+ if (TargetStatement == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, No match HII statement is found by the
given %s in schema %a\n", __FUNCTION__, ConfigureLang, Schema));
+ return EFI_NOT_FOUND;
+ }
+
+ if (StatementValue->Type != TargetStatement->HiiStatement-
Value.Type) {
+ //
+ // We treat one-of type as string in Redfish. But one-of statement is not
+ // in string format from HII point of view. Do a patch here.
+ //
+ if (TargetStatement->HiiStatement->Operand == EFI_IFR_ONE_OF_OP
&& StatementValue->Type == EFI_IFR_TYPE_STRING) {
+
+ TempBuffer = StrToUnicodeStr ((CHAR8 *)StatementValue->Buffer);
+ if (TempBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ FreePool (StatementValue->Buffer);
+ StatementValue->Buffer = NULL;
+ StatementValue->BufferLen = 0;
+
+ Status = HiiStringToOneOfOptionValue (TargetStatement, Schema,
TempBuffer, StatementValue);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to find option value by the given
%s\n", __FUNCTION__, TempBuffer));
+ FreePool (TempBuffer);
+ return EFI_NOT_FOUND;
+ }
+
+ FreePool (TempBuffer);
+ } else if (TargetStatement->HiiStatement->Operand ==
EFI_IFR_ORDERED_LIST_OP && StatementValue->Type ==
EFI_IFR_TYPE_STRING) {
+ //
+ // We treat ordered list type as string in Redfish. But ordered list
statement is not
+ // in string format from HII point of view. Do a patch here.
+ //
+ StringArray = AllocateZeroPool (TargetStatement->HiiStatement-
StorageWidth);
+ if (StringArray == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Arrage new option order from input string array
+ //
+ CharArray = (CHAR8 **)StatementValue->Buffer;
+ for (Index = 0; Index < StatementValue->BufferLen; Index++) {
+ TempBuffer = StrToUnicodeStr (CharArray[Index]);
+ if (TempBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = HiiStringToOrderedListOptionValue (TargetStatement, Schema,
TempBuffer, &Value);
+ if (EFI_ERROR (Status)) {
+ ASSERT (FALSE);
+ continue;
+ }
+ FreePool (TempBuffer);
+ OrderedListSetArrayData (StringArray, TargetStatement->HiiStatement-
Value.BufferValueType, Index, Value);
+ }
+
+ StatementValue->Type = EFI_IFR_TYPE_BUFFER;
+ StatementValue->Buffer = StringArray;
+ StatementValue->BufferLen = TargetStatement->HiiStatement-
StorageWidth;
+ StatementValue->BufferValueType = TargetStatement->HiiStatement-
Value.BufferValueType;
+ } else if (TargetStatement->HiiStatement->Operand ==
EFI_IFR_NUMERIC_OP && StatementValue->Type ==
EFI_IFR_TYPE_NUM_SIZE_64) {
+ //
+ // Redfish only has numeric value type and it does not care about the
value size.
+ // Do a patch here so we have proper value size applied.
+ //
+ StatementValue->Type = TargetStatement->HiiStatement->Value.Type;
+ } else {
+ DEBUG ((DEBUG_ERROR, "%a, catch value type mismatch! input type:
0x%x but target value type: 0x%x\n", __FUNCTION__, StatementValue-
Type, TargetStatement->HiiStatement->Value.Type));
+ ASSERT (FALSE);
+ }
+ }
+
+ Status = RedfishPlatformConfigSaveQuestionValue (
+ TargetStatement->ParentForm->ParentFormset->HiiFormSet,
+ TargetStatement->ParentForm->HiiForm,
+ TargetStatement->HiiStatement,
+ StatementValue
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to save question value: %r\n",
__FUNCTION__, Status));
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Set Redfish value with the given Schema and Configure Language.
+
+ @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+ @param[in] Schema The Redfish schema to query.
+ @param[in] Version The Redfish version to query.
+ @param[in] ConfigureLang The target value which match this configure
Language.
+ @param[in] Value The value to set.
+
+ @retval EFI_SUCCESS Value is returned successfully.
+ @retval Others Some error happened.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformConfigProtocolSetValue (
+ IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+ IN CHAR8 *Schema,
+ IN CHAR8 *Version,
+ IN EFI_STRING ConfigureLang,
+ IN EDKII_REDFISH_VALUE Value
+ )
+{
+ EFI_STATUS Status;
+ REDFISH_PLATFORM_CONFIG_PRIVATE
*RedfishPlatformConfigPrivate;
+ CHAR8 *FullSchema;
+ HII_STATEMENT_VALUE NewValue;
+
+ if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
(Version) || IS_EMPTY_STRING (ConfigureLang)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Value.Type == REDFISH_VALUE_TYPE_UNKNOWN || Value.Type >=
REDFISH_VALUE_TYPE_MAX) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ RedfishPlatformConfigPrivate =
REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
+ FullSchema = NULL;
+
+ FullSchema = GetFullSchemaString (Schema, Version);
+ if (FullSchema == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ZeroMem (&NewValue, sizeof (HII_STATEMENT_VALUE));
+
+ switch (Value.Type) {
+ case REDFISH_VALUE_TYPE_INTEGER:
+ case REDFISH_VALUE_TYPE_BOOLEAN:
+ Status = RedfishNumericToHiiValue (&Value, &NewValue);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to convert Redfish value to Hii
value: %r\n", __FUNCTION__, Status));
+ goto RELEASE_RESOURCE;
+ }
+ break;
+ case REDFISH_VALUE_TYPE_STRING:
+ NewValue.Type = EFI_IFR_TYPE_STRING;
+ NewValue.BufferLen = (UINT16)AsciiStrSize (Value.Value.Buffer);
+ NewValue.Buffer = AllocateCopyPool (NewValue.BufferLen,
Value.Value.Buffer);
+ if (NewValue.Buffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto RELEASE_RESOURCE;
+ }
+ break;
+ case REDFISH_VALUE_TYPE_STRING_ARRAY:
+ NewValue.Type = EFI_IFR_TYPE_STRING;
+ NewValue.BufferLen = (UINT16)Value.ArrayCount;
+ NewValue.Buffer = (UINT8 *)Value.Value.StringArray;
+ break;
+ default:
+ ASSERT (FALSE);
+ break;
+ }
+
+ Status = RedfishPlatformConfigSetStatementCommon
(RedfishPlatformConfigPrivate, FullSchema, ConfigureLang, &NewValue);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to set value to statement: %r\n",
__FUNCTION__, Status));
+ }
+
+RELEASE_RESOURCE:
+
+ if (FullSchema != NULL) {
+ FreePool (FullSchema);
+ }
+
+ return Status;
+}
+
+/**
+ Get the list of Configure Language from platform configuration by the
given Schema and RegexPattern.
+
+ @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+ @param[in] Schema The Redfish schema to query.
+ @param[in] Version The Redfish version to query.
+ @param[in] RegexPattern The target Configure Language pattern.
This is used for regular expression matching.
+ @param[out] ConfigureLangList The list of Configure Language.
+ @param[out] Count The number of Configure Language in
ConfigureLangList.
+
+ @retval EFI_SUCCESS ConfigureLangList is returned successfully.
+ @retval Others Some error happened.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformConfigProtocolGetConfigureLang (
+ IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+ IN CHAR8 *Schema,
+ IN CHAR8 *Version,
+ IN EFI_STRING RegexPattern,
+ OUT EFI_STRING **ConfigureLangList,
+ OUT UINTN *Count
+ )
+{
+ REDFISH_PLATFORM_CONFIG_PRIVATE
*RedfishPlatformConfigPrivate;
+ EFI_STATUS Status;
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST StatementList;
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF
*StatementRef;
+ LIST_ENTRY *NextLink;
+ EFI_STRING TmpString;
+ EFI_STRING *TmpConfigureLangList;
+ UINTN Index;
+ CHAR8 *FullSchema;
+
+ if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
(Version) || Count == NULL || ConfigureLangList == NULL ||
IS_EMPTY_STRING (RegexPattern)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Count = 0;
+ *ConfigureLangList = NULL;
+ FullSchema = NULL;
+ RedfishPlatformConfigPrivate =
REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
+
+ Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
&RedfishPlatformConfigPrivate->PendingList);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
__FUNCTION__, Status));
+ return Status;
+ }
+
+ FullSchema = GetFullSchemaString (Schema, Version);
+ if (FullSchema == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = GetStatementPrivateByConfigureLangRegex (
+ RedfishPlatformConfigPrivate->RegularExpressionProtocol,
+ &RedfishPlatformConfigPrivate->FormsetList,
+ FullSchema,
+ RegexPattern,
+ &StatementList
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a,
GetStatementPrivateByConfigureLangRegex failure: %r\n", __FUNCTION__,
Status));
+ goto RELEASE_RESOURCE;
+ }
+
+ if (!IsListEmpty (&StatementList.StatementList)) {
+
+ TmpConfigureLangList = AllocateZeroPool (sizeof (CHAR16 *) *
StatementList.Count);
+ if (TmpConfigureLangList == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto RELEASE_RESOURCE;
+ }
+
+ Index = 0;
+ NextLink = GetFirstNode (&StatementList.StatementList);
+ while (!IsNull (&StatementList.StatementList, NextLink)) {
+ StatementRef =
REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
+ NextLink = GetNextNode (&StatementList.StatementList, NextLink);
+
+ ASSERT (StatementRef->Statement->Description != 0);
+ if (StatementRef->Statement->Description != 0) {
+ TmpString = HiiGetRedfishString (StatementRef->Statement-
ParentForm->ParentFormset->HiiHandle, FullSchema, StatementRef-
Statement->Description);
+ ASSERT (TmpString != NULL);
+ if (TmpString != NULL) {
+ TmpConfigureLangList[Index] = AllocateCopyPool (StrSize (TmpString),
TmpString);
+ ASSERT (TmpConfigureLangList[Index] != NULL);
+ FreePool (TmpString);
+ ++Index;
+ }
+ }
+ }
+ }
+
+ *Count = StatementList.Count;
+ *ConfigureLangList = TmpConfigureLangList;
+
+RELEASE_RESOURCE:
+
+ if (FullSchema != NULL) {
+ FreePool (FullSchema);
+ }
+
+ ReleaseStatementList (&StatementList);
+
+ return Status;
+}
+
+/**
+ Get the list of supported Redfish schema from paltform configuration on
give HII handle.
+
+ @param[in] This Pointer to
EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+ @param[in] HiiHandle The target handle to search. If handle is NULL,
+ this function return all schema from HII database.
+ @param[out] SupportedSchema The supported schema list which is
separated by ';'.
+ The SupportedSchema is allocated by the callee. It's
caller's
+ responsibility to free this buffer using FreePool().
+
+ @retval EFI_SUCCESS Schema is returned successfully.
+ @retval Others Some error happened.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformConfigProtocolGetSupportedSchema (
+ IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+ IN EFI_HII_HANDLE HiiHandle, OPTIONAL
+ OUT CHAR8 **SupportedSchema
+ )
+{
+ REDFISH_PLATFORM_CONFIG_PRIVATE
*RedfishPlatformConfigPrivate;
+ EFI_STATUS Status;
+ LIST_ENTRY *HiiFormsetLink;
+ LIST_ENTRY *HiiFormsetNextLink;
+ REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
+ UINTN Index;
+ UINTN StringSize;
+ CHAR8 *StringBuffer;
+ UINTN StringIndex;
+
+ if (This == NULL || SupportedSchema == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *SupportedSchema = NULL;
+
+ RedfishPlatformConfigPrivate =
REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
+
+ Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
&RedfishPlatformConfigPrivate->PendingList);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
__FUNCTION__, Status));
+ return Status;
+ }
+
+ if (IsListEmpty (&RedfishPlatformConfigPrivate->FormsetList)) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Calculate for string buffer size.
+ //
+ StringSize = 0;
+ HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate-
FormsetList);
+ while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList,
HiiFormsetLink)) {
+ HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate-
FormsetList, HiiFormsetLink);
+ HiiFormsetPrivate =
REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+ if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
+ HiiFormsetLink = HiiFormsetNextLink;
+ continue;
+ }
+
+ if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
+ for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count;
Index++) {
+ StringSize += AsciiStrSize (HiiFormsetPrivate-
SupportedSchema.SchemaList[Index]);
+ }
+ }
+
+ HiiFormsetLink = HiiFormsetNextLink;
+ }
+
+ if (StringSize == 0) {
+ return EFI_NOT_FOUND;
+ }
+
+ StringBuffer = AllocatePool (StringSize);
+ if (StringBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ StringIndex = 0;
+ HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate-
FormsetList);
+ while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList,
HiiFormsetLink)) {
+ HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate-
FormsetList, HiiFormsetLink);
+ HiiFormsetPrivate =
REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+ if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
+ HiiFormsetLink = HiiFormsetNextLink;
+ continue;
+ }
+
+ if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
+ for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count;
Index++) {
+ AsciiStrCpyS (&StringBuffer[StringIndex], (StringSize - StringIndex),
HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
+ StringIndex += AsciiStrLen (HiiFormsetPrivate-
SupportedSchema.SchemaList[Index]);
+ StringBuffer[StringIndex] = ';';
+ ++StringIndex;
+ }
+ }
+
+ HiiFormsetLink = HiiFormsetNextLink;
+ }
+
+ StringBuffer[--StringIndex] = '\0';
+
+ *SupportedSchema = StringBuffer;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Functions which are registered to receive notification of
+ database events have this prototype. The actual event is encoded
+ in NotifyType. The following table describes how PackageType,
+ PackageGuid, Handle, and Package are used for each of the
+ notification types.
+
+ @param[in] PackageType Package type of the notification.
+ @param[in] PackageGuid If PackageType is
+ EFI_HII_PACKAGE_TYPE_GUID, then this is
+ the pointer to the GUID from the Guid
+ field of EFI_HII_PACKAGE_GUID_HEADER.
+ Otherwise, it must be NULL.
+ @param[in] Package Points to the package referred to by the
+ notification Handle The handle of the package
+ list which contains the specified package.
+ @param[in] Handle The HII handle.
+ @param[in] NotifyType The type of change concerning the
+ database. See
+ EFI_HII_DATABASE_NOTIFY_TYPE.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformConfigFormUpdateNotify (
+ IN UINT8 PackageType,
+ IN CONST EFI_GUID *PackageGuid,
+ IN CONST EFI_HII_PACKAGE_HEADER *Package,
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
+ )
+{
+ EFI_STATUS Status;
+
+ if (NotifyType == EFI_HII_DATABASE_NOTIFY_NEW_PACK || NotifyType
== EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
+ //
+ // HII formset on this handle is updated by driver during run-time. The
formset needs to be reloaded.
+ //
+ Status = NotifyFormsetUpdate (Handle,
&mRedfishPlatformConfigPrivate->PendingList);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to notify updated formset of HII
handle: 0x%x\n", __FUNCTION__, Handle));
+ return Status;
+ }
+ } else if (NotifyType == EFI_HII_DATABASE_NOTIFY_REMOVE_PACK) {
+ //
+ // HII resource is removed. The formset is no longer exist.
+ //
+ Status = NotifyFormsetDeleted (Handle,
&mRedfishPlatformConfigPrivate->PendingList);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to notify deleted formset of HII
handle: 0x%x\n", __FUNCTION__, Handle));
+ return Status;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This is a EFI_HII_STRING_PROTOCOL notification event handler.
+
+ Install HII package notification.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context Pointer to the notification function's context.
+
+**/
+VOID
+EFIAPI
+HiiStringProtocolInstalled (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Locate HII database protocol.
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiHiiStringProtocolGuid,
+ NULL,
+ (VOID **)&mRedfishPlatformConfigPrivate->HiiString
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, locate EFI_HII_STRING_PROTOCOL failure:
%r\n", __FUNCTION__, Status));
+ return;
+ }
+
+ gBS->CloseEvent (Event);
+ mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent = NULL;
+}
+
+/**
+ This is a EFI_HII_DATABASE_PROTOCOL notification event handler.
+
+ Install HII package notification.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context Pointer to the notification function's context.
+
+**/
+VOID
+EFIAPI
+HiiDatabaseProtocolInstalled (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Locate HII database protocol.
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiHiiDatabaseProtocolGuid,
+ NULL,
+ (VOID **)&mRedfishPlatformConfigPrivate->HiiDatabase
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, locate EFI_HII_DATABASE_PROTOCOL
failure: %r\n", __FUNCTION__, Status));
+ return;
+ }
+
+ //
+ // Register package notification when new form package is installed.
+ //
+ Status = mRedfishPlatformConfigPrivate->HiiDatabase-
RegisterPackageNotify (
+ mRedfishPlatformConfigPrivate->HiiDatabase,
+ EFI_HII_PACKAGE_FORMS,
+ NULL,
+ RedfishPlatformConfigFormUpdateNotify,
+ EFI_HII_DATABASE_NOTIFY_NEW_PACK,
+ &mRedfishPlatformConfigPrivate->NotifyHandle
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for
EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__,
Status));
+ }
+
+ //
+ // Register package notification when new form package is updated.
+ //
+ Status = mRedfishPlatformConfigPrivate->HiiDatabase-
RegisterPackageNotify (
+ mRedfishPlatformConfigPrivate->HiiDatabase,
+ EFI_HII_PACKAGE_FORMS,
+ NULL,
+ RedfishPlatformConfigFormUpdateNotify,
+ EFI_HII_DATABASE_NOTIFY_ADD_PACK,
+ &mRedfishPlatformConfigPrivate->NotifyHandle
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for
EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__,
Status));
+ }
+
+ gBS->CloseEvent (Event);
+ mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent = NULL;
+
+}
+
+/**
+ This is a EFI_REGULAR_EXPRESSION_PROTOCOL notification event handler.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context Pointer to the notification function's context.
+
+**/
+VOID
+EFIAPI
+RegexProtocolInstalled (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Locate regular expression protocol.
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiRegularExpressionProtocolGuid,
+ NULL,
+ (VOID **)&mRedfishPlatformConfigPrivate-
RegularExpressionProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, locate
EFI_REGULAR_EXPRESSION_PROTOCOL failure: %r\n", __FUNCTION__,
Status));
+ return;
+ }
+
+ gBS->CloseEvent (Event);
+ mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent = NULL;
+
+}
+
+/**
+ Unloads an image.
+
+ @param ImageHandle Handle that identifies the image to be
unloaded.
+
+ @retval EFI_SUCCESS The image has been unloaded.
+ @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image
handle.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformConfigDxeUnload (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+
+ if (mRedfishPlatformConfigPrivate != NULL) {
+ Status = gBS->UninstallProtocolInterface (
+ mRedfishPlatformConfigPrivate->ImageHandle,
+ &gEdkIIRedfishPlatformConfigProtocolGuid,
+ (VOID*)&mRedfishPlatformConfigPrivate->Protocol
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, can not uninstall
gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
+ ASSERT (FALSE);
+ }
+
+ //
+ // Close events
+ //
+ if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent != NULL) {
+ gBS->CloseEvent (mRedfishPlatformConfigPrivate-
HiiDbNotify.ProtocolEvent);
+ }
+ if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent !=
NULL) {
+ gBS->CloseEvent (mRedfishPlatformConfigPrivate-
HiiStringNotify.ProtocolEvent);
+ }
+ if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent != NULL)
{
+ gBS->CloseEvent (mRedfishPlatformConfigPrivate-
RegexNotify.ProtocolEvent);
+ }
+
+ //
+ // Unregister package notification.
+ //
+ if (mRedfishPlatformConfigPrivate->NotifyHandle != NULL) {
+ mRedfishPlatformConfigPrivate->HiiDatabase->UnregisterPackageNotify
(
+ mRedfishPlatformConfigPrivate->HiiDatabase,
+ mRedfishPlatformConfigPrivate->NotifyHandle
+ );
+ }
+
+ ReleaseFormsetList (&mRedfishPlatformConfigPrivate->FormsetList);
+ FreePool (mRedfishPlatformConfigPrivate);
+ mRedfishPlatformConfigPrivate = NULL;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This is the declaration of an EFI image entry point. This entry point is
+ the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
+ both device drivers and bus drivers.
+
+ @param ImageHandle The firmware allocated handle for the UEFI
image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval Others An unexpected error occurred.
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformConfigDxeEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ mRedfishPlatformConfigPrivate = (REDFISH_PLATFORM_CONFIG_PRIVATE
*)AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PRIVATE));
+ if (mRedfishPlatformConfigPrivate == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, can not allocate pool for
REDFISH_PLATFORM_CONFIG_PRIVATE\n", __FUNCTION__));
+ ASSERT (FALSE);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Protocol initialization
+ //
+ mRedfishPlatformConfigPrivate->ImageHandle = ImageHandle;
+ mRedfishPlatformConfigPrivate->Protocol.GetValue =
RedfishPlatformConfigProtocolGetValue;
+ mRedfishPlatformConfigPrivate->Protocol.SetValue =
RedfishPlatformConfigProtocolSetValue;
+ mRedfishPlatformConfigPrivate->Protocol.GetConfigureLang =
RedfishPlatformConfigProtocolGetConfigureLang;
+ mRedfishPlatformConfigPrivate->Protocol.GetSupportedSchema =
RedfishPlatformConfigProtocolGetSupportedSchema;
+
+ InitializeListHead (&mRedfishPlatformConfigPrivate->FormsetList);
+ InitializeListHead (&mRedfishPlatformConfigPrivate->PendingList);
+
+ Status = gBS->InstallProtocolInterface (
+ &ImageHandle,
+ &gEdkIIRedfishPlatformConfigProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ (VOID*)&mRedfishPlatformConfigPrivate->Protocol
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, can not install
gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
+ ASSERT (FALSE);
+ }
+
+ //
+ // Install protocol notification if HII database protocol is installed.
+ //
+ mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent =
EfiCreateProtocolNotifyEvent (
+ &gEfiHiiDatabaseProtocolGuid,
+ TPL_CALLBACK,
+ HiiDatabaseProtocolInstalled,
+ NULL,
+ &mRedfishPlatformConfigPrivate-
HiiDbNotify.Registration
+ );
+ if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
gEfiHiiDatabaseProtocolGuid\n", __FUNCTION__));
+ ASSERT (FALSE);
+ }
+
+ //
+ // Install protocol notification if HII string protocol is installed.
+ //
+ mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent =
EfiCreateProtocolNotifyEvent (
+ &gEfiHiiStringProtocolGuid,
+ TPL_CALLBACK,
+ HiiStringProtocolInstalled,
+ NULL,
+ &mRedfishPlatformConfigPrivate-
HiiStringNotify.Registration
+ );
+ if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent == NULL)
{
+ DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
gEfiHiiStringProtocolGuid\n", __FUNCTION__));
+ ASSERT (FALSE);
+ }
+
+ //
+ // Install protocol notification if regular expression protocol is installed.
+ //
+ mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent =
EfiCreateProtocolNotifyEvent (
+ &gEfiRegularExpressionProtocolGuid,
+ TPL_CALLBACK,
+ RegexProtocolInstalled,
+ NULL,
+ &mRedfishPlatformConfigPrivate-
RegexNotify.Registration
+ );
+ if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
gEfiRegularExpressionProtocolGuid\n", __FUNCTION__));
+ ASSERT (FALSE);
+ }
+
+ return EFI_SUCCESS;
+}
diff --git
a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
index 99a613d229..d3f7af55ad 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
@@ -1,64 +1,64 @@
-/** @file
- This file defines the EDKII Redfish Platform Config Protocol interface.
-
- (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
-#define EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
-
-#include <Uefi.h>
-
-//
-// Libraries
-//
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/PrintLib.h>
-#include <Library/UefiLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiDriverEntryPoint.h>
-
-//
-// Produced Protocols
-//
-#include <Protocol/EdkIIRedfishPlatformConfig.h>
-#include <Protocol/HiiDatabase.h>
-#include <Protocol/HiiString.h>
-#include <Protocol/RegularExpressionProtocol.h>
-
-//
-// Definition of EDKII_REDFISH_PLATFORM_CONFIG_NOTIFY.
-//
-typedef struct {
- EFI_EVENT ProtocolEvent; // Protocol notification event.
- VOID *Registration; // Protocol notification registration.
-} REDFISH_PLATFORM_CONFIG_NOTIFY;
-
-//
-// Definition of REDFISH_PLATFORM_CONFIG_PRIVATE.
-//
-typedef struct {
- EFI_HANDLE ImageHandle; // Driver image handle.
- EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL Protocol;
- REDFISH_PLATFORM_CONFIG_NOTIFY HiiDbNotify;
- EFI_HII_DATABASE_PROTOCOL *HiiDatabase; // The HII
database protocol.
- REDFISH_PLATFORM_CONFIG_NOTIFY HiiStringNotify;
- EFI_HII_STRING_PROTOCOL *HiiString; // HII String
Protocol.
- REDFISH_PLATFORM_CONFIG_NOTIFY RegexNotify;
- EFI_REGULAR_EXPRESSION_PROTOCOL *RegularExpressionProtocol;
// Regular Expression Protocol.
- EFI_HANDLE NotifyHandle; // The notify handle.
- LIST_ENTRY FormsetList; // The list to keep cached
HII formset.
- LIST_ENTRY PendingList; // The list to keep updated
HII handle.
-} REDFISH_PLATFORM_CONFIG_PRIVATE;
-
-#define REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS(a) BASE_CR
(a, REDFISH_PLATFORM_CONFIG_PRIVATE, Protocol)
-#define REGULAR_EXPRESSION_INCLUDE_ALL L".*"
-#define CONFIGURE_LANGUAGE_PREFIX "x-uefi-redfish-"
-
-#endif
+/** @file
+ This file defines the EDKII Redfish Platform Config Protocol interface.
+
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
+#define EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
+
+#include <Uefi.h>
+
+//
+// Libraries
+//
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+
+//
+// Produced Protocols
+//
+#include <Protocol/EdkIIRedfishPlatformConfig.h>
+#include <Protocol/HiiDatabase.h>
+#include <Protocol/HiiString.h>
+#include <Protocol/RegularExpressionProtocol.h>
+
+//
+// Definition of EDKII_REDFISH_PLATFORM_CONFIG_NOTIFY.
+//
+typedef struct {
+ EFI_EVENT ProtocolEvent; // Protocol notification event.
+ VOID *Registration; // Protocol notification registration.
+} REDFISH_PLATFORM_CONFIG_NOTIFY;
+
+//
+// Definition of REDFISH_PLATFORM_CONFIG_PRIVATE.
+//
+typedef struct {
+ EFI_HANDLE ImageHandle; // Driver image handle.
+ EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL Protocol;
+ REDFISH_PLATFORM_CONFIG_NOTIFY HiiDbNotify;
+ EFI_HII_DATABASE_PROTOCOL *HiiDatabase; // The HII
database protocol.
+ REDFISH_PLATFORM_CONFIG_NOTIFY HiiStringNotify;
+ EFI_HII_STRING_PROTOCOL *HiiString; // HII String
Protocol.
+ REDFISH_PLATFORM_CONFIG_NOTIFY RegexNotify;
+ EFI_REGULAR_EXPRESSION_PROTOCOL *RegularExpressionProtocol;
// Regular Expression Protocol.
+ EFI_HANDLE NotifyHandle; // The notify handle.
+ LIST_ENTRY FormsetList; // The list to keep cached
HII formset.
+ LIST_ENTRY PendingList; // The list to keep updated
HII handle.
+} REDFISH_PLATFORM_CONFIG_PRIVATE;
+
+#define REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS(a) BASE_CR
(a, REDFISH_PLATFORM_CONFIG_PRIVATE, Protocol)
+#define REGULAR_EXPRESSION_INCLUDE_ALL L".*"
+#define CONFIGURE_LANGUAGE_PREFIX "x-uefi-redfish-"
+
+#endif
diff --git
a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf
b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf
index 16739bef7a..81b22e03c3 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf
@@ -1,53 +1,53 @@
-## @file
-# Implementation of EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL
interfaces.
-#
-# (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = RedfishPlatformConfigDxe
- FILE_GUID = BEAEFFE1-0633-41B5-913C-9389339C2927
- MODULE_TYPE = DXE_DRIVER
- VERSION_STRING = 1.0
- ENTRY_POINT = RedfishPlatformConfigDxeEntryPoint
- UNLOAD_IMAGE = RedfishPlatformConfigDxeUnload
-
-[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
- RedfishPkg/RedfishPkg.dec
-
-[Sources]
- RedfishPlatformConfigDxe.h
- RedfishPlatformConfigDxe.c
- RedfishPlatformConfigImpl.h
- RedfishPlatformConfigImpl.c
-
-[LibraryClasses]
- BaseLib
- BaseMemoryLib
- DebugLib
- DevicePathLib
- HiiLib
- HiiUtilityLib
- MemoryAllocationLib
- PrintLib
- UefiLib
- UefiBootServicesTableLib
- UefiRuntimeServicesTableLib
- UefiDriverEntryPoint
-
-[Protocols]
- gEdkIIRedfishPlatformConfigProtocolGuid ## PRODUCED
- gEfiHiiDatabaseProtocolGuid ## CONSUMED
- gEfiHiiStringProtocolGuid ## CONSUMED
- gEfiRegularExpressionProtocolGuid ## CONSUMED
-
-[Guids]
- gEfiRegexSyntaxTypePerlGuid ## CONSUMED
-
-[Depex]
+## @file
+# Implementation of EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL
interfaces.
+#
+# (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = RedfishPlatformConfigDxe
+ FILE_GUID = BEAEFFE1-0633-41B5-913C-9389339C2927
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = RedfishPlatformConfigDxeEntryPoint
+ UNLOAD_IMAGE = RedfishPlatformConfigDxeUnload
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ RedfishPkg/RedfishPkg.dec
+
+[Sources]
+ RedfishPlatformConfigDxe.h
+ RedfishPlatformConfigDxe.c
+ RedfishPlatformConfigImpl.h
+ RedfishPlatformConfigImpl.c
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ DevicePathLib
+ HiiLib
+ HiiUtilityLib
+ MemoryAllocationLib
+ PrintLib
+ UefiLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+ UefiDriverEntryPoint
+
+[Protocols]
+ gEdkIIRedfishPlatformConfigProtocolGuid ## PRODUCED
+ gEfiHiiDatabaseProtocolGuid ## CONSUMED
+ gEfiHiiStringProtocolGuid ## CONSUMED
+ gEfiRegularExpressionProtocolGuid ## CONSUMED
+
+[Guids]
+ gEfiRegexSyntaxTypePerlGuid ## CONSUMED
+
+[Depex]
TRUE
\ No newline at end of file
diff --git
a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
index d9eab6c883..917f946656 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
@@ -1,1240 +1,1288 @@
-/** @file
-
- The implementation of EDKII Redfidh Platform Config Protocol.
-
- (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-#include "RedfishPlatformConfigDxe.h"
-#include "RedfishPlatformConfigImpl.h"
-
-extern REDFISH_PLATFORM_CONFIG_PRIVATE
*mRedfishPlatformConfigPrivate;
-
-/**
- Debug dump HII string
-
- @param[in] HiiHandle HII handle instance
- @param[in] StringId HII string to dump
-
- @retval EFI_SUCCESS Dump HII string successfully
- @retval Others Errors occur
-
-**/
-EFI_STATUS
-DumpHiiString (
- IN EFI_HII_HANDLE HiiHandle,
- IN EFI_STRING_ID StringId
- )
-{
- EFI_STRING String;
-
- if (HiiHandle == NULL || StringId == 0) {
- DEBUG ((DEBUG_INFO, "???"));
- return EFI_INVALID_PARAMETER;
- }
-
- String = HiiGetString (HiiHandle, StringId, NULL);
- if (String == NULL) {
- return EFI_NOT_FOUND;
- }
-
- DEBUG ((DEBUG_INFO, "%s", String));
- FreePool (String);
-
- return EFI_SUCCESS;
-}
-
-/**
- Debug dump HII form-set data
-
- @param[in] FormsetPrivate HII form-set private instance.
-
- @retval EFI_SUCCESS Dump form-set successfully
- @retval Others Errors occur
-
-**/
-EFI_STATUS
-DumpFormset (
- IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate
- )
-{
- LIST_ENTRY *HiiFormLink;
- LIST_ENTRY *HiiNextFormLink;
- REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate;
- LIST_ENTRY *HiiStatementLink;
- LIST_ENTRY *HiiNextStatementLink;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
*HiiStatementPrivate;
- UINTN Index;
-
- if (FormsetPrivate == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- Index = 0;
- HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
- while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
- HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
(HiiFormLink);
- HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList,
HiiFormLink);
-
- DEBUG ((DEBUG_INFO, " [%d] form: %d title: ", ++Index, HiiFormPrivate-
Id));
- DumpHiiString (FormsetPrivate->HiiHandle, HiiFormPrivate->Title);
- DEBUG ((DEBUG_INFO, "\n"));
-
- HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
- while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
- HiiStatementPrivate =
REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
- HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
HiiStatementLink);
-
- DEBUG ((DEBUG_INFO, " QID: 0x%x Prompt: ", HiiStatementPrivate-
QuestionId));
- DumpHiiString (FormsetPrivate->HiiHandle, HiiStatementPrivate-
Description);
- DEBUG ((DEBUG_INFO, "\n"));
-
- HiiStatementLink = HiiNextStatementLink;
- }
-
- HiiFormLink = HiiNextFormLink;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Debug dump HII form-set list
-
- @param[in] FormsetList Form-set list instance
-
- @retval EFI_SUCCESS Dump list successfully
- @retval Others Errors occur
-
-**/
-EFI_STATUS
-DumpFormsetList (
- IN LIST_ENTRY *FormsetList
- )
-{
- LIST_ENTRY *HiiFormsetLink;
- LIST_ENTRY *HiiFormsetNextLink;
- REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
- UINTN Index;
-
- if (FormsetList == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (IsListEmpty (FormsetList)) {
- DEBUG ((DEBUG_INFO, "%a, Empty formset list\n", __FUNCTION__));
- return EFI_SUCCESS;
- }
-
- Index = 0;
- HiiFormsetLink = GetFirstNode (FormsetList);
- while (!IsNull (FormsetList, HiiFormsetLink)) {
- HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
- HiiFormsetPrivate =
REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
- DEBUG ((DEBUG_INFO, "[%d] HII Handle: 0x%x formset: %g at %s\n",
++Index, HiiFormsetPrivate->HiiHandle, &HiiFormsetPrivate->Guid,
HiiFormsetPrivate->DevicePathStr));
- DumpFormset (HiiFormsetPrivate);
-
- HiiFormsetLink = HiiFormsetNextLink;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Retrieves a string from a string package in a English language. The
- returned string is allocated using AllocatePool(). The caller is responsible
- for freeing the allocated buffer using FreePool().
-
- If HiiHandle is NULL, then ASSERT().
- If StringId is 0, then ASSET.
-
- @param[in] HiiStringProtocol EFI_HII_STRING_PROTOCOL instance.
- @param[in] HiiHandle A handle that was previously registered in the
HII Database.
- @param[in] StringId The identifier of the string to retrieved from the
string
- package associated with HiiHandle.
-
- @retval NULL The string specified by StringId is not present in the string
package.
- @retval Other The string was returned.
-
-**/
-EFI_STRING
-HiiGetRedfishString (
- IN EFI_HII_HANDLE HiiHandle,
- IN CHAR8 *Language,
- IN EFI_STRING_ID StringId
- )
-{
- EFI_STATUS Status;
- UINTN StringSize;
- CHAR16 TempString;
- EFI_STRING String;
-
- if (mRedfishPlatformConfigPrivate->HiiString == NULL || HiiHandle == NULL
|| StringId == 0 || IS_EMPTY_STRING (Language)) {
- ASSERT (FALSE);
- return NULL;
- }
-
- //
- // Retrieve the size of the string in the string package for the BestLanguage
- //
- StringSize = 0;
- Status = mRedfishPlatformConfigPrivate->HiiString->GetString (
- mRedfishPlatformConfigPrivate->HiiString,
- Language,
- HiiHandle,
- StringId,
- &TempString,
- &StringSize,
- NULL
- );
- //
- // If GetString() returns EFI_SUCCESS for a zero size,
- // then there are no supported languages registered for HiiHandle. If
GetString()
- // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is
not present
- // in the HII Database
- //
- if (Status != EFI_BUFFER_TOO_SMALL) {
- return NULL;
- }
-
- //
- // Allocate a buffer for the return string
- //
- String = AllocateZeroPool (StringSize);
- if (String == NULL) {
- return NULL;
- }
-
- //
- // Retrieve the string from the string package
- //
- Status = mRedfishPlatformConfigPrivate->HiiString->GetString (
- mRedfishPlatformConfigPrivate->HiiString,
- Language,
- HiiHandle,
- StringId,
- String,
- &StringSize,
- NULL
- );
- if (EFI_ERROR (Status)) {
- //
- // Free the buffer and return NULL if the supported languages can not be
retrieved.
- //
- FreePool (String);
- String = NULL;
- }
-
- //
- // Return the Null-terminated Unicode string
- //
- return String;
-}
-
-/**
- Get string from HII database in English language.
-
- @param[in] HiiHandle A handle that was previously registered in the
HII Database.
- @param[in] StringId The identifier of the string to retrieved from the
string
- package associated with HiiHandle.
-
- @retval NULL The string specified by StringId is not present in the string
package.
- @retval Other The string was returned.
-
-**/
-EFI_STRING
-HiiGetEnglishString (
- IN EFI_HII_HANDLE HiiHandle,
- IN EFI_STRING_ID StringId
- )
-{
- return HiiGetRedfishString (HiiHandle, ENGLISH_LANGUAGE_CODE,
StringId);
-}
-
-/**
- Check and see if this is supported schema or not.
-
- @param[in] SupportedSchema The list of supported schema.
- @param[in] Schema Schema string to be checked.
-
- @retval BOOLEAN TRUE if this is supported schema. FALSE
otherwise.
-
-**/
-BOOLEAN
-CheckSupportedSchema (
- IN REDFISH_PLATFORM_CONFIG_SCHEMA *SupportedSchema,
- IN CHAR8 *Schema
- )
-{
- UINTN Index;
-
- if (SupportedSchema == NULL || IS_EMPTY_STRING (Schema)) {
- return FALSE;
- }
-
- if (SupportedSchema->Count == 0) {
- return FALSE;
- }
-
- for (Index = 0; Index < SupportedSchema->Count; Index++) {
- if (AsciiStrCmp (SupportedSchema->SchemaList[Index], Schema) == 0) {
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-/**
- Get the list of supported schema from the given HII handle.
-
- @param[in] HiiHandle HII handle instance.
- @param[out] SupportedSchema Supported schema on this HII handle.
-
- @retval EFI_SUCCESS Schema list is returned.
- @retval EFI_INVALID_PARAMETER HiiHandle is NULL or SupportedSchema
is NULL.
- @retval EFI_NOT_FOUND No supported schema found.
- @retval EFI_OUT_OF_RESOURCES System is out of memory.
-
-**/
-EFI_STATUS
-GetSupportedSchema (
- IN EFI_HII_HANDLE HiiHandle,
- OUT REDFISH_PLATFORM_CONFIG_SCHEMA *SupportedSchema
- )
-{
- CHAR8 *SupportedLanguages;
- UINTN Index;
- UINTN LangIndex;
- UINTN Count;
- UINTN StrSize;
- UINTN ListIndex;
-
- if (HiiHandle == NULL || SupportedSchema == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- SupportedSchema->Count = 0;
-
- SupportedLanguages = HiiGetSupportedLanguages (HiiHandle);
- if (SupportedLanguages == NULL) {
- return EFI_NOT_FOUND;
- }
-
- Index = 0;
- LangIndex = 0;
- Count = 0;
- while (TRUE) {
- if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] ==
'\0') {
- if (AsciiStrnCmp (&SupportedLanguages[LangIndex],
X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
- ++Count;
- }
- LangIndex = Index + 1;
- }
-
- if (SupportedLanguages[Index] == '\0') {
- break;
- }
-
- ++Index;
- }
-
- if (Count == 0) {
- return EFI_NOT_FOUND;
- }
-
- SupportedSchema->Count = Count;
- SupportedSchema->SchemaList = AllocatePool (sizeof (CHAR8 *) * Count);
- if (SupportedSchema->SchemaList == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Index = 0;
- LangIndex = 0;
- ListIndex = 0;
- while (TRUE) {
-
- if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] ==
'\0') {
- if (AsciiStrnCmp (&SupportedLanguages[LangIndex],
X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
- StrSize = Index - LangIndex;
- SupportedSchema->SchemaList[ListIndex] = AllocateCopyPool ((StrSize
+ 1), &SupportedLanguages[LangIndex]);
- SupportedSchema->SchemaList[ListIndex][StrSize] = '\0';
- ++ListIndex;
- }
-
- LangIndex = Index + 1;
- }
-
- if (SupportedLanguages[Index] == '\0') {
- break;
- }
-
- ++Index;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Search and find statement private instance by given regular expression
patthern
- which describes the Configure Language.
-
- @param[in] RegularExpressionProtocol Regular express protocol.
- @param[in] FormsetList Form-set list to search.
- @param[in] Schema Schema to be matched.
- @param[in] Pattern Regular expression pattern.
- @param[out] StatementList Statement list that match above
pattern.
-
- @retval EFI_SUCCESS Statement list is returned.
- @retval EFI_INVALID_PARAMETER Input parameter is NULL.
- @retval EFI_NOT_READY Regular express protocol is NULL.
- @retval EFI_NOT_FOUND No statement is found.
- @retval EFI_OUT_OF_RESOURCES System is out of memory.
-
-**/
-EFI_STATUS
-GetStatementPrivateByConfigureLangRegex (
- IN EFI_REGULAR_EXPRESSION_PROTOCOL
*RegularExpressionProtocol,
- IN LIST_ENTRY *FormsetList,
- IN CHAR8 *Schema,
- IN EFI_STRING Pattern,
- OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
*StatementList
- )
-{
- LIST_ENTRY *HiiFormsetLink;
- LIST_ENTRY *HiiFormsetNextLink;
- REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
- LIST_ENTRY *HiiFormLink;
- LIST_ENTRY *HiiNextFormLink;
- REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate;
- LIST_ENTRY *HiiStatementLink;
- LIST_ENTRY *HiiNextStatementLink;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
*HiiStatementPrivate;
- EFI_STRING TmpString;
- UINTN CaptureCount;
- BOOLEAN IsMatch;
- EFI_STATUS Status;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF *StatementRef;
-
- if (FormsetList == NULL || IS_EMPTY_STRING (Schema) ||
IS_EMPTY_STRING (Pattern) || StatementList == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (RegularExpressionProtocol == NULL) {
- return EFI_NOT_READY;
- }
-
- StatementList->Count = 0;
- InitializeListHead (&StatementList->StatementList);
-
- if (IsListEmpty (FormsetList)) {
- return EFI_NOT_FOUND;
- }
-
- HiiFormsetLink = GetFirstNode (FormsetList);
- while (!IsNull (FormsetList, HiiFormsetLink)) {
- HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
- HiiFormsetPrivate =
REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
- //
- // Performance check.
- // If there is no desired Redfish schema found, skip this formset.
- //
- if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema,
Schema)) {
- HiiFormsetLink = HiiFormsetNextLink;
- continue;
- }
-
- HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
- while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
- HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList,
HiiFormLink);
- HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
(HiiFormLink);
-
- HiiStatementLink =GetFirstNode (&HiiFormPrivate->StatementList);
- while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
- HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
HiiStatementLink);
- HiiStatementPrivate =
REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
-
- if (HiiStatementPrivate->Description != 0) {
- TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle,
Schema, HiiStatementPrivate->Description);
- if (TmpString != NULL) {
- Status = RegularExpressionProtocol->MatchString (
- RegularExpressionProtocol,
- TmpString,
- Pattern,
- &gEfiRegexSyntaxTypePerlGuid,
- &IsMatch,
- NULL,
- &CaptureCount
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, MatchString \"%s\" failed: %r\n",
__FUNCTION__, Pattern, Status));
- ASSERT (FALSE);
- return Status;
- }
-
- //
- // Found
- //
- if (IsMatch) {
- StatementRef = AllocateZeroPool (sizeof
(REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF));
- if (StatementRef == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- StatementRef->Statement = HiiStatementPrivate;
- InsertTailList (&StatementList->StatementList, &StatementRef->Link);
- ++StatementList->Count;
- }
-
- FreePool (TmpString);
- }
- }
-
- HiiStatementLink = HiiNextStatementLink;
- }
-
- HiiFormLink = HiiNextFormLink;
- }
-
- HiiFormsetLink = HiiFormsetNextLink;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Get statement private instance by the given configure language.
-
- @param[in] FormsetList Form-set list to search.
- @param[in] Schema Schema to be matched.
- @param[in] ConfigureLang Configure language.
-
- @retval REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE * Pointer to
statement private instance.
-
-**/
-REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *
-GetStatementPrivateByConfigureLang (
- IN LIST_ENTRY *FormsetList,
- IN CHAR8 *Schema,
- IN EFI_STRING ConfigureLang
- )
-{
- LIST_ENTRY *HiiFormsetLink;
- LIST_ENTRY *HiiFormsetNextLink;
- REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
- LIST_ENTRY *HiiFormLink;
- LIST_ENTRY *HiiNextFormLink;
- REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate;
- LIST_ENTRY *HiiStatementLink;
- LIST_ENTRY *HiiNextStatementLink;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
*HiiStatementPrivate;
- EFI_STRING TmpString;
-
- if (FormsetList == NULL || IS_EMPTY_STRING (Schema) ||
IS_EMPTY_STRING (ConfigureLang)) {
- return NULL;
- }
-
- if (IsListEmpty (FormsetList)) {
- return NULL;
- }
-
- HiiFormsetLink = GetFirstNode (FormsetList);
- while (!IsNull (FormsetList, HiiFormsetLink)) {
- HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
- HiiFormsetPrivate =
REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
- //
- // Performance check.
- // If there is no desired Redfish schema found, skip this formset.
- //
- if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema,
Schema)) {
- HiiFormsetLink = HiiFormsetNextLink;
- continue;
- }
-
- HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
- while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
- HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList,
HiiFormLink);
- HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
(HiiFormLink);
-
- HiiStatementLink =GetFirstNode (&HiiFormPrivate->StatementList);
- while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
- HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
HiiStatementLink);
- HiiStatementPrivate =
REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
-
- DEBUG_CODE (
- STATIC UINTN Index = 0;
- DEBUG ((DEBUG_INFO, "%a, [%d] search %s in QID: 0x%x form: 0x%x
formset: %g\n", __FUNCTION__, ++Index, ConfigureLang,
HiiStatementPrivate->QuestionId, HiiFormPrivate->Id, &HiiFormsetPrivate-
Guid));
- );
-
- if (HiiStatementPrivate->Description != 0) {
- TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle,
Schema, HiiStatementPrivate->Description);
- if (TmpString != NULL) {
- if (StrCmp (TmpString, ConfigureLang) == 0) {
- FreePool (TmpString);
- return HiiStatementPrivate;
- }
-
- FreePool (TmpString);
- }
- }
-
- HiiStatementLink = HiiNextStatementLink;
- }
-
- HiiFormLink = HiiNextFormLink;
- }
-
- HiiFormsetLink = HiiFormsetNextLink;
- }
-
- return NULL;
-}
-
-/**
- Get form-set private instance by the given HII handle.
-
- @param[in] HiiHandle HII handle instance.
- @param[in] FormsetList Form-set list to search.
-
- @retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE * Pointer to
form-set private instance.
-
-**/
-REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *
-GetFormsetPrivateByHiiHandle (
- IN EFI_HII_HANDLE HiiHandle,
- IN LIST_ENTRY *FormsetList
- )
-{
- LIST_ENTRY *HiiFormsetLink;
- LIST_ENTRY *HiiFormsetNextLink;
- REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
-
- if (HiiHandle == NULL || FormsetList == NULL) {
- return NULL;
- }
-
- if (IsListEmpty (FormsetList)) {
- return NULL;
- }
-
- HiiFormsetLink = GetFirstNode (FormsetList);
- while (!IsNull (FormsetList, HiiFormsetLink)) {
- HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
- HiiFormsetPrivate =
REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
- if (HiiFormsetPrivate->HiiHandle == HiiHandle) {
- return HiiFormsetPrivate;
- }
-
- HiiFormsetLink = HiiFormsetNextLink;
- }
-
- return NULL;
-}
-
-/**
- Release formset and all the forms and statements that belong to this
formset.
-
- @param[in] FormsetPrivate Pointer to HP_HII_FORM_SET_PRIVATE
-
- @retval EFI_STATUS
-
-**/
-EFI_STATUS
-ReleaseFormset (
- IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate
- )
-{
- LIST_ENTRY *HiiFormLink;
- LIST_ENTRY *HiiNextFormLink;
- REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate;
- LIST_ENTRY *HiiStatementLink;
- LIST_ENTRY *HiiNextStatementLink;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
*HiiStatementPrivate;
- UINTN Index;
-
- if (FormsetPrivate == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
- while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
- HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
(HiiFormLink);
- HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList,
HiiFormLink);
-
- HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
- while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
- HiiStatementPrivate =
REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
- HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
HiiStatementLink);
-
- //
- // HiiStatementPrivate->HiiStatement will be released in
DestroyFormSet().
- //
-
- if (HiiStatementPrivate->DesStringCache != NULL) {
- FreePool (HiiStatementPrivate->DesStringCache);
- HiiStatementPrivate->DesStringCache = NULL;
- }
-
- RemoveEntryList (&HiiStatementPrivate->Link);
- FreePool (HiiStatementPrivate);
- HiiStatementLink = HiiNextStatementLink;
- }
-
- //
- // HiiStatementPrivate->HiiForm will be released in DestroyFormSet().
- //
-
- RemoveEntryList (&HiiFormPrivate->Link);
- FreePool (HiiFormPrivate);
- HiiFormLink = HiiNextFormLink;
- }
-
- if (FormsetPrivate->HiiFormSet != NULL) {
- DestroyFormSet (FormsetPrivate->HiiFormSet);
- FormsetPrivate->HiiFormSet = NULL;
- }
-
- FreePool (FormsetPrivate->DevicePathStr);
-
- //
- // Release schema list
- //
- if (FormsetPrivate->SupportedSchema.SchemaList != NULL) {
- for (Index = 0; Index < FormsetPrivate->SupportedSchema.Count;
Index++) {
- FreePool (FormsetPrivate->SupportedSchema.SchemaList[Index]);
- }
-
- FreePool (FormsetPrivate->SupportedSchema.SchemaList);
- FormsetPrivate->SupportedSchema.SchemaList = NULL;
- FormsetPrivate->SupportedSchema.Count = 0;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Create new form-set instance.
-
- @retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE * Pointer to
newly created form-set private instance.
-
-**/
-REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *
-NewFormsetPrivate (
- VOID
- )
-{
- REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *NewFormsetPrivate;
-
- NewFormsetPrivate = AllocateZeroPool (sizeof
(REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE));
- if (NewFormsetPrivate == NULL) {
- return NULL;
- }
-
- //
- // Initial newly created formset private data.
- //
- InitializeListHead (&NewFormsetPrivate->HiiFormList);
-
- return NewFormsetPrivate;
-}
-
-/**
- Load the HII formset from the given HII handle.
-
- @param[in] HiiHandle Target HII handle to load.
- @param[out] FormsetPrivate The formset private data.
-
- @retval EFI_STATUS
-
-**/
-EFI_STATUS
-LoadFormset (
- IN EFI_HII_HANDLE HiiHandle,
- OUT REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate
- )
-{
- EFI_STATUS Status;
- HII_FORMSET *HiiFormSet;
- HII_FORM *HiiForm;
- LIST_ENTRY *HiiFormLink;
- REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate;
- HII_STATEMENT *HiiStatement;
- LIST_ENTRY *HiiStatementLink;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
*HiiStatementPrivate;
- EFI_GUID ZeroGuid;
-
- if (HiiHandle == NULL || FormsetPrivate == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
-
- HiiFormSet = AllocateZeroPool (sizeof (HII_FORMSET));
- if (HiiFormSet == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Find HII formset by the given HII handle.
- //
- ZeroMem (&ZeroGuid, sizeof (ZeroGuid));
- Status = CreateFormSetFromHiiHandle (HiiHandle, &ZeroGuid, HiiFormSet);
- if (EFI_ERROR (Status) || IsListEmpty (&HiiFormSet->FormListHead)) {
- Status = EFI_NOT_FOUND;
- goto ErrorExit;
- }
-
- //
- // Initialize formset
- //
- InitializeFormSet (HiiFormSet);
-
- //
- // Initialize formset private data.
- //
- FormsetPrivate->HiiFormSet = HiiFormSet;
- FormsetPrivate->HiiHandle = HiiHandle;
- CopyGuid (&FormsetPrivate->Guid, &HiiFormSet->Guid);
- FormsetPrivate->DevicePathStr = ConvertDevicePathToText (HiiFormSet-
DevicePath, FALSE, FALSE);
- Status = GetSupportedSchema (FormsetPrivate->HiiHandle,
&FormsetPrivate->SupportedSchema);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_WARN, "%a, No schema from HII handle: 0x%x found:
%r\n", __FUNCTION__, FormsetPrivate->HiiHandle, Status));
- }
-
- HiiFormLink = GetFirstNode (&HiiFormSet->FormListHead);
- while (!IsNull (&HiiFormSet->FormListHead, HiiFormLink)) {
- HiiForm = HII_FORM_FROM_LINK (HiiFormLink);
-
- HiiFormPrivate = AllocateZeroPool (sizeof
(REDFISH_PLATFORM_CONFIG_FORM_PRIVATE));
- if (HiiFormPrivate == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ErrorExit;
- }
-
- //
- // Initialize form private data.
- //
- HiiFormPrivate->HiiForm = HiiForm;
- HiiFormPrivate->Id = HiiForm->FormId;
- HiiFormPrivate->Title = HiiForm->FormTitle;
- HiiFormPrivate->ParentFormset = FormsetPrivate;
- InitializeListHead (&HiiFormPrivate->StatementList);
-
- HiiStatementLink = GetFirstNode (&HiiForm->StatementListHead);
- while (!IsNull (&HiiForm->StatementListHead, HiiStatementLink)) {
- HiiStatement = HII_STATEMENT_FROM_LINK (HiiStatementLink);
-
- HiiStatementPrivate = AllocateZeroPool (sizeof
(REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE));
- if (HiiStatementPrivate == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto ErrorExit;
- }
- //
- // Initialize statement private data.
- //
- HiiStatementPrivate->HiiStatement = HiiStatement;
- HiiStatementPrivate->QuestionId = HiiStatement->QuestionId;
- HiiStatementPrivate->Description = HiiStatement->Prompt;
- HiiStatementPrivate->ParentForm = HiiFormPrivate;
-
- //
- // Attach to statement list.
- //
- InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate-
Link);
- HiiStatementLink = GetNextNode (&HiiForm->StatementListHead,
HiiStatementLink);
- }
- //
- // Attach to form list.
- //
- InsertTailList (&FormsetPrivate->HiiFormList, &HiiFormPrivate->Link);
- HiiFormLink = GetNextNode (&HiiFormSet->FormListHead, HiiFormLink);
- }
-
- return EFI_SUCCESS;
-
-ErrorExit:
-
- //
- // Release HiiFormSet if HiiFormSet is not linked to FormsetPrivate yet.
- //
- if (HiiFormSet != NULL && FormsetPrivate->HiiFormSet != HiiFormSet) {
- DestroyFormSet (HiiFormSet);
- }
-
- //
- // Release resource when error happens.
- //
- ReleaseFormset (FormsetPrivate);
-
- return Status;
-}
-
-/**
- Release formset list and all the forms that belong to this formset.
-
- @param[in] FormsetList Pointer to formst list that needs to be
- released.
-
- @retval EFI_STATUS
-
-**/
-EFI_STATUS
-LoadFormsetList (
- IN EFI_HII_HANDLE *HiiHandle,
- OUT LIST_ENTRY *FormsetList
- )
-{
- EFI_STATUS Status;
- REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate;
-
- if (HiiHandle == NULL || FormsetList == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- FormsetPrivate = GetFormsetPrivateByHiiHandle (HiiHandle, FormsetList);
- if (FormsetPrivate != NULL) {
- return EFI_ALREADY_STARTED;
- }
-
- FormsetPrivate = NewFormsetPrivate ();
- if (FormsetPrivate == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__));
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Load formset on the given HII handle.
- //
- Status = LoadFormset (HiiHandle, FormsetPrivate);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to load formset: %r\n",
__FUNCTION__, Status));
- FreePool (FormsetPrivate);
- return Status;
- }
-
- //
- // Attach to cache list.
- //
- InsertTailList (FormsetList, &FormsetPrivate->Link);
-
- DEBUG_CODE (
- DumpFormsetList (FormsetList);
- );
-
- return EFI_SUCCESS;
-}
-
-/**
- Release formset list and all the forms that belong to this formset.
-
- @param[in] FormsetList Pointer to formst list that needs to be
- released.
-
- @retval EFI_STATUS
-
-**/
-EFI_STATUS
-ReleaseFormsetList (
- IN LIST_ENTRY *FormsetList
- )
-{
- LIST_ENTRY *HiiFormsetLink;
- LIST_ENTRY *HiiFormsetNextLink;
- REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
-
- if (FormsetList == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (IsListEmpty (FormsetList)) {
- return EFI_SUCCESS;
- }
-
- HiiFormsetLink = GetFirstNode (FormsetList);
- while (!IsNull (FormsetList, HiiFormsetLink)) {
- HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
- HiiFormsetPrivate =
REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
- //
- // Detach from list.
- //
- RemoveEntryList (&HiiFormsetPrivate->Link);
- ReleaseFormset (HiiFormsetPrivate);
- FreePool (HiiFormsetPrivate);
- HiiFormsetLink = HiiFormsetNextLink;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Get all pending list.
-
- @param[in] HiiHandle HII handle instance.
- @param[in] PendingList Pending list to keep pending data.
-
- @retval REDFISH_PLATFORM_CONFIG_PENDING_LIST * Pointer to
pending list data.
-
-**/
-REDFISH_PLATFORM_CONFIG_PENDING_LIST *
-GetPendingList (
- IN EFI_HII_HANDLE *HiiHandle,
- IN LIST_ENTRY *PendingList
- )
-{
- LIST_ENTRY *PendingListLink;
- REDFISH_PLATFORM_CONFIG_PENDING_LIST *Target;
-
- if (HiiHandle == NULL || PendingList == NULL) {
- return NULL;
- }
-
- if (IsListEmpty (PendingList)) {
- return NULL;
- }
-
- PendingListLink = GetFirstNode (PendingList);
- while (!IsNull (PendingList, PendingListLink)) {
- Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK
(PendingListLink);
-
- if (Target->HiiHandle == HiiHandle) {
- return Target;
- }
-
- PendingListLink = GetNextNode (PendingList, PendingListLink);
- }
-
- return NULL;
-}
-
-/**
- When HII database is updated. Keep updated HII handle into pending list so
- we can process them later.
-
- @param[in] HiiHandle HII handle instance.
- @param[in] PendingList Pending list to keep HII handle which is recently
updated.
-
- @retval EFI_SUCCESS HII handle is saved in pending list.
- @retval EFI_INVALID_PARAMETER HiiHnalde is NULL or PendingList is
NULL.
- @retval EFI_OUT_OF_RESOURCES System is out of memory.
-
-**/
-EFI_STATUS
-NotifyFormsetUpdate (
- IN EFI_HII_HANDLE *HiiHandle,
- IN LIST_ENTRY *PendingList
- )
-{
- REDFISH_PLATFORM_CONFIG_PENDING_LIST *TargetPendingList;
-
- if (HiiHandle == NULL || PendingList == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check and see if this HII handle is processed already.
- //
- TargetPendingList = GetPendingList (HiiHandle, PendingList);
- if (TargetPendingList != NULL) {
- TargetPendingList->IsDeleted = FALSE;
- DEBUG_CODE (
- DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated\n",
__FUNCTION__, HiiHandle));
- );
- return EFI_SUCCESS;
- }
-
- TargetPendingList= AllocateZeroPool (sizeof
(REDFISH_PLATFORM_CONFIG_PENDING_LIST));
- if (TargetPendingList == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- TargetPendingList->HiiHandle = HiiHandle;
- TargetPendingList->IsDeleted = FALSE;
-
- InsertTailList (PendingList, &TargetPendingList->Link);
-
- DEBUG_CODE (
- DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is created\n",
__FUNCTION__, HiiHandle));
- );
-
- return EFI_SUCCESS;
-}
-
-/**
- When HII database is updated and form-set is deleted. Keep deleted HII
handle into pending list so
- we can process them later.
-
- @param[in] HiiHandle HII handle instance.
- @param[in] PendingList Pending list to keep HII handle which is recently
updated.
-
- @retval EFI_SUCCESS HII handle is saved in pending list.
- @retval EFI_INVALID_PARAMETER HiiHnalde is NULL or PendingList is
NULL.
- @retval EFI_OUT_OF_RESOURCES System is out of memory.
-
-**/
-EFI_STATUS
-NotifyFormsetDeleted (
- IN EFI_HII_HANDLE *HiiHandle,
- IN LIST_ENTRY *PendingList
- )
-{
- REDFISH_PLATFORM_CONFIG_PENDING_LIST *TargetPendingList;
-
- if (HiiHandle == NULL || PendingList == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check and see if this HII handle is processed already.
- //
- TargetPendingList = GetPendingList (HiiHandle, PendingList);
- if (TargetPendingList != NULL) {
- TargetPendingList->IsDeleted = TRUE;
- DEBUG_CODE (
- DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated and deleted\n",
__FUNCTION__, HiiHandle));
- );
- return EFI_SUCCESS;
- }
-
- TargetPendingList= AllocateZeroPool (sizeof
(REDFISH_PLATFORM_CONFIG_PENDING_LIST));
- if (TargetPendingList == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- TargetPendingList->HiiHandle = HiiHandle;
- TargetPendingList->IsDeleted = TRUE;
-
- InsertTailList (PendingList, &TargetPendingList->Link);
-
- DEBUG_CODE (
- DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is deleted\n",
__FUNCTION__, HiiHandle));
- );
-
- return EFI_SUCCESS;
-}
-
-/**
- There are HII database update and we need to process them accordingly so
that we
- won't use stale data. This function will parse updated HII handle again in
order
- to get updated data-set.
-
- @param[in] FormsetList List to keep HII form-set.
- @param[in] PendingList List to keep HII handle that is updated.
-
- @retval EFI_SUCCESS HII handle is saved in pending list.
- @retval EFI_INVALID_PARAMETER FormsetList is NULL or PendingList is
NULL.
-
-**/
-EFI_STATUS
-ProcessPendingList (
- IN LIST_ENTRY *FormsetList,
- IN LIST_ENTRY *PendingList
- )
-{
- LIST_ENTRY *PendingListLink;
- LIST_ENTRY *PendingListNextLink;
- REDFISH_PLATFORM_CONFIG_PENDING_LIST *Target;
- REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate;
- EFI_STATUS Status;
-
-
- if (FormsetList == NULL || PendingList == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (IsListEmpty (PendingList)) {
- return EFI_SUCCESS;
- }
-
- PendingListLink = GetFirstNode (PendingList);
- while (!IsNull (PendingList, PendingListLink)) {
- PendingListNextLink = GetNextNode (PendingList, PendingListLink);
- Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK
(PendingListLink);
-
- if (Target->IsDeleted) {
- //
- // The HII resource on this HII handle is removed. Release the formset.
- //
- FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle,
FormsetList);
- if (FormsetPrivate != NULL) {
- DEBUG ((DEBUG_INFO, "%a, formset: %g is removed because driver
release HII resource it already\n", __FUNCTION__, FormsetPrivate->Guid));
- RemoveEntryList (&FormsetPrivate->Link);
- ReleaseFormset (FormsetPrivate);
- FreePool (FormsetPrivate);
- } else {
- DEBUG ((DEBUG_WARN, "%a, formset on HII handle 0x%x was removed
already\n", __FUNCTION__, Target->HiiHandle));
- }
- } else {
- //
- // The HII resource on this HII handle is updated/removed.
- //
- FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle,
FormsetList);
- if (FormsetPrivate != NULL) {
- //
- // HII formset already exist, release it and query again.
- //
- DEBUG ((DEBUG_INFO, "%a, formset: %g is updated. Release current
formset\n", __FUNCTION__, &FormsetPrivate->Guid));
- RemoveEntryList (&FormsetPrivate->Link);
- ReleaseFormset (FormsetPrivate);
- FreePool (FormsetPrivate);
- }
-
- Status = LoadFormsetList (Target->HiiHandle, FormsetList);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, load formset from HII handle: 0x%x failed:
%r\n", __FUNCTION__, Target->HiiHandle, Status));
- }
- }
-
- //
- // Detach it from list first.
- //
- RemoveEntryList (&Target->Link);
- FreePool (Target);
-
- PendingListLink = PendingListNextLink;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Release all resource in statement list.
-
- @param[in] StatementList Statement list to be released.
-
- @retval EFI_SUCCESS All resource are released.
- @retval EFI_INVALID_PARAMETER StatementList is NULL.
-
-**/
-EFI_STATUS
-ReleaseStatementList (
- IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
*StatementList
- )
-{
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF *StatementRef;
- LIST_ENTRY *NextLink;
-
- if (StatementList == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (IsListEmpty (&StatementList->StatementList)) {
- return EFI_SUCCESS;
- }
-
- NextLink = GetFirstNode (&StatementList->StatementList);
- while (!IsNull (&StatementList->StatementList, NextLink)) {
- StatementRef =
REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
- NextLink = GetNextNode (&StatementList->StatementList, NextLink);
-
- RemoveEntryList (&StatementRef->Link);
- FreePool (StatementRef);
- }
-
- return EFI_SUCCESS;
-}
+/** @file
+
+ The implementation of EDKII Redfidh Platform Config Protocol.
+
+ (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include "RedfishPlatformConfigDxe.h"
+#include "RedfishPlatformConfigImpl.h"
+
+extern REDFISH_PLATFORM_CONFIG_PRIVATE
*mRedfishPlatformConfigPrivate;
+
+/**
+ Debug dump HII string
+
+ @param[in] HiiHandle HII handle instance
+ @param[in] StringId HII string to dump
+
+ @retval EFI_SUCCESS Dump HII string successfully
+ @retval Others Errors occur
+
+**/
+EFI_STATUS
+DumpHiiString (
+ IN EFI_HII_HANDLE HiiHandle,
+ IN EFI_STRING_ID StringId
+ )
+{
+ EFI_STRING String;
+
+ if (HiiHandle == NULL || StringId == 0) {
+ DEBUG ((DEBUG_INFO, "???"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ String = HiiGetString (HiiHandle, StringId, NULL);
+ if (String == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ DEBUG ((DEBUG_INFO, "%s", String));
+ FreePool (String);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Debug dump HII form-set data
+
+ @param[in] FormsetPrivate HII form-set private instance.
+
+ @retval EFI_SUCCESS Dump form-set successfully
+ @retval Others Errors occur
+
+**/
+EFI_STATUS
+DumpFormset (
+ IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate
+ )
+{
+ LIST_ENTRY *HiiFormLink;
+ LIST_ENTRY *HiiNextFormLink;
+ REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate;
+ LIST_ENTRY *HiiStatementLink;
+ LIST_ENTRY *HiiNextStatementLink;
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
*HiiStatementPrivate;
+ UINTN Index;
+
+ if (FormsetPrivate == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Index = 0;
+ HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
+ while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
+ HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
(HiiFormLink);
+ HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList,
HiiFormLink);
+
+ DEBUG ((DEBUG_INFO, " [%d] form: %d title: ", ++Index, HiiFormPrivate-
Id));
+ DumpHiiString (FormsetPrivate->HiiHandle, HiiFormPrivate->Title);
+ DEBUG ((DEBUG_INFO, "\n"));
+
+ HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
+ while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
+ HiiStatementPrivate =
REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
+ HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
HiiStatementLink);
+
+ DEBUG ((DEBUG_INFO, " QID: 0x%x Prompt: ", HiiStatementPrivate-
QuestionId));
+ DumpHiiString (FormsetPrivate->HiiHandle, HiiStatementPrivate-
Description);
+ DEBUG ((DEBUG_INFO, "\n"));
+
+ HiiStatementLink = HiiNextStatementLink;
+ }
+
+ HiiFormLink = HiiNextFormLink;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Debug dump HII form-set list
+
+ @param[in] FormsetList Form-set list instance
+
+ @retval EFI_SUCCESS Dump list successfully
+ @retval Others Errors occur
+
+**/
+EFI_STATUS
+DumpFormsetList (
+ IN LIST_ENTRY *FormsetList
+ )
+{
+ LIST_ENTRY *HiiFormsetLink;
+ LIST_ENTRY *HiiFormsetNextLink;
+ REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
+ UINTN Index;
+
+ if (FormsetList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (IsListEmpty (FormsetList)) {
+ DEBUG ((DEBUG_INFO, "%a, Empty formset list\n", __FUNCTION__));
+ return EFI_SUCCESS;
+ }
+
+ Index = 0;
+ HiiFormsetLink = GetFirstNode (FormsetList);
+ while (!IsNull (FormsetList, HiiFormsetLink)) {
+ HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
+ HiiFormsetPrivate =
REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+ DEBUG ((DEBUG_INFO, "[%d] HII Handle: 0x%x formset: %g at %s\n",
++Index, HiiFormsetPrivate->HiiHandle, &HiiFormsetPrivate->Guid,
HiiFormsetPrivate->DevicePathStr));
+ DumpFormset (HiiFormsetPrivate);
+
+ HiiFormsetLink = HiiFormsetNextLink;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Retrieves a string from a string package in a English language. The
+ returned string is allocated using AllocatePool(). The caller is responsible
+ for freeing the allocated buffer using FreePool().
+
+ If HiiHandle is NULL, then ASSERT().
+ If StringId is 0, then ASSET.
+
+ @param[in] HiiStringProtocol EFI_HII_STRING_PROTOCOL instance.
+ @param[in] HiiHandle A handle that was previously registered in the
HII Database.
+ @param[in] StringId The identifier of the string to retrieved from the
string
+ package associated with HiiHandle.
+
+ @retval NULL The string specified by StringId is not present in the string
package.
+ @retval Other The string was returned.
+
+**/
+EFI_STRING
+HiiGetRedfishString (
+ IN EFI_HII_HANDLE HiiHandle,
+ IN CHAR8 *Language,
+ IN EFI_STRING_ID StringId
+ )
+{
+ EFI_STATUS Status;
+ UINTN StringSize;
+ CHAR16 TempString;
+ EFI_STRING String;
+
+ if (mRedfishPlatformConfigPrivate->HiiString == NULL || HiiHandle ==
NULL || StringId == 0 || IS_EMPTY_STRING (Language)) {
+ ASSERT (FALSE);
+ return NULL;
+ }
+
+ //
+ // Retrieve the size of the string in the string package for the BestLanguage
+ //
+ StringSize = 0;
+ Status = mRedfishPlatformConfigPrivate->HiiString->GetString (
+ mRedfishPlatformConfigPrivate->HiiString,
+ Language,
+ HiiHandle,
+ StringId,
+ &TempString,
+ &StringSize,
+ NULL
+ );
+ //
+ // If GetString() returns EFI_SUCCESS for a zero size,
+ // then there are no supported languages registered for HiiHandle. If
GetString()
+ // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is
not present
+ // in the HII Database
+ //
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ return NULL;
+ }
+
+ //
+ // Allocate a buffer for the return string
+ //
+ String = AllocateZeroPool (StringSize);
+ if (String == NULL) {
+ return NULL;
+ }
+
+ //
+ // Retrieve the string from the string package
+ //
+ Status = mRedfishPlatformConfigPrivate->HiiString->GetString (
+ mRedfishPlatformConfigPrivate->HiiString,
+ Language,
+ HiiHandle,
+ StringId,
+ String,
+ &StringSize,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // Free the buffer and return NULL if the supported languages can not be
retrieved.
+ //
+ FreePool (String);
+ String = NULL;
+ }
+
+ //
+ // Return the Null-terminated Unicode string
+ //
+ return String;
+}
+
+/**
+ Retrieves a string from a string package in a English language. The
+ returned string is allocated using AllocatePool(). The caller is responsible
+ for freeing the allocated buffer using FreePool().
+
+ If HiiHandle is NULL, then ASSERT().
+ If StringId is 0, then ASSET.
+
+ @param[in] HiiStringProtocol EFI_HII_STRING_PROTOCOL instance.
+ @param[in] HiiHandle A handle that was previously registered in the
HII Database.
+ @param[in] StringId The identifier of the string to retrieved from the
The function parameters are not correct.

string
+ package associated with HiiHandle.
+
+ @retval NULL The string specified by StringId is not present in the string
package.
+ @retval Other The string was returned.
+
+**/
+CHAR8 *
+HiiGetRedfishAsciiString (
+ IN EFI_HII_HANDLE HiiHandle,
+ IN CHAR8 *Language,
+ IN EFI_STRING_ID StringId
+ )
+{
+ EFI_STRING HiiString;
+ UINTN StringSize;
+ CHAR8 *AsciiString;
+
+ HiiString = HiiGetRedfishString (HiiHandle, Language, StringId);
+ if (HiiString == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, Can not find string ID: 0x%x with %a\n",
__FUNCTION__, StringId, Language));
+ return NULL;
+ }
+
+ StringSize = (StrLen (HiiString) + 1) * sizeof (CHAR8);
+ AsciiString = AllocatePool (StringSize);
+ if (AsciiString == NULL) {
+ return NULL;
+ }
+
+ UnicodeStrToAsciiStrS (HiiString, AsciiString, StringSize);
+
+ FreePool (HiiString);
+ return AsciiString;
+}
+
+/**
+ Get string from HII database in English language.
+
+ @param[in] HiiHandle A handle that was previously registered in the
HII Database.
+ @param[in] StringId The identifier of the string to retrieved from the
string
+ package associated with HiiHandle.
+
+ @retval NULL The string specified by StringId is not present in the string
package.
+ @retval Other The string was returned.
+
+**/
+EFI_STRING
+HiiGetEnglishString (
+ IN EFI_HII_HANDLE HiiHandle,
+ IN EFI_STRING_ID StringId
+ )
+{
+ return HiiGetRedfishString (HiiHandle, ENGLISH_LANGUAGE_CODE,
StringId);
+}
+
+/**
+ Check and see if this is supported schema or not.
+
+ @param[in] SupportedSchema The list of supported schema.
+ @param[in] Schema Schema string to be checked.
+
+ @retval BOOLEAN TRUE if this is supported schema. FALSE
otherwise.
+
+**/
+BOOLEAN
+CheckSupportedSchema (
+ IN REDFISH_PLATFORM_CONFIG_SCHEMA *SupportedSchema,
+ IN CHAR8 *Schema
+ )
+{
+ UINTN Index;
+
+ if (SupportedSchema == NULL || IS_EMPTY_STRING (Schema)) {
+ return FALSE;
+ }
+
+ if (SupportedSchema->Count == 0) {
+ return FALSE;
+ }
+
+ for (Index = 0; Index < SupportedSchema->Count; Index++) {
+ if (AsciiStrCmp (SupportedSchema->SchemaList[Index], Schema) == 0) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ Get the list of supported schema from the given HII handle.
+
+ @param[in] HiiHandle HII handle instance.
+ @param[out] SupportedSchema Supported schema on this HII handle.
+
+ @retval EFI_SUCCESS Schema list is returned.
+ @retval EFI_INVALID_PARAMETER HiiHandle is NULL or SupportedSchema
is NULL.
+ @retval EFI_NOT_FOUND No supported schema found.
+ @retval EFI_OUT_OF_RESOURCES System is out of memory.
+
+**/
+EFI_STATUS
+GetSupportedSchema (
+ IN EFI_HII_HANDLE HiiHandle,
+ OUT REDFISH_PLATFORM_CONFIG_SCHEMA *SupportedSchema
+ )
+{
+ CHAR8 *SupportedLanguages;
+ UINTN Index;
+ UINTN LangIndex;
+ UINTN Count;
+ UINTN StrSize;
+ UINTN ListIndex;
+
+ if (HiiHandle == NULL || SupportedSchema == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ SupportedSchema->Count = 0;
+
+ SupportedLanguages = HiiGetSupportedLanguages (HiiHandle);
+ if (SupportedLanguages == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ Index = 0;
+ LangIndex = 0;
+ Count = 0;
+ while (TRUE) {
+ if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] ==
'\0') {
+ if (AsciiStrnCmp (&SupportedLanguages[LangIndex],
X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
+ ++Count;
+ }
+ LangIndex = Index + 1;
+ }
+
+ if (SupportedLanguages[Index] == '\0') {
+ break;
+ }
+
+ ++Index;
+ }
+
+ if (Count == 0) {
+ return EFI_NOT_FOUND;
+ }
+
+ SupportedSchema->Count = Count;
+ SupportedSchema->SchemaList = AllocatePool (sizeof (CHAR8 *) * Count);
+ if (SupportedSchema->SchemaList == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Index = 0;
+ LangIndex = 0;
+ ListIndex = 0;
+ while (TRUE) {
+
+ if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] ==
'\0') {
+ if (AsciiStrnCmp (&SupportedLanguages[LangIndex],
X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
+ StrSize = Index - LangIndex;
+ SupportedSchema->SchemaList[ListIndex] = AllocateCopyPool ((StrSize
+ 1), &SupportedLanguages[LangIndex]);
+ SupportedSchema->SchemaList[ListIndex][StrSize] = '\0';
+ ++ListIndex;
+ }
+
+ LangIndex = Index + 1;
+ }
+
+ if (SupportedLanguages[Index] == '\0') {
+ break;
+ }
+
+ ++Index;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Search and find statement private instance by given regular expression
patthern
+ which describes the Configure Language.
+
+ @param[in] RegularExpressionProtocol Regular express protocol.
+ @param[in] FormsetList Form-set list to search.
+ @param[in] Schema Schema to be matched.
+ @param[in] Pattern Regular expression pattern.
+ @param[out] StatementList Statement list that match above
pattern.
+
+ @retval EFI_SUCCESS Statement list is returned.
+ @retval EFI_INVALID_PARAMETER Input parameter is NULL.
+ @retval EFI_NOT_READY Regular express protocol is NULL.
+ @retval EFI_NOT_FOUND No statement is found.
+ @retval EFI_OUT_OF_RESOURCES System is out of memory.
+
+**/
+EFI_STATUS
+GetStatementPrivateByConfigureLangRegex (
+ IN EFI_REGULAR_EXPRESSION_PROTOCOL
*RegularExpressionProtocol,
+ IN LIST_ENTRY *FormsetList,
+ IN CHAR8 *Schema,
+ IN EFI_STRING Pattern,
+ OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
*StatementList
+ )
+{
+ LIST_ENTRY *HiiFormsetLink;
+ LIST_ENTRY *HiiFormsetNextLink;
+ REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
+ LIST_ENTRY *HiiFormLink;
+ LIST_ENTRY *HiiNextFormLink;
+ REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate;
+ LIST_ENTRY *HiiStatementLink;
+ LIST_ENTRY *HiiNextStatementLink;
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
*HiiStatementPrivate;
+ EFI_STRING TmpString;
+ UINTN CaptureCount;
+ BOOLEAN IsMatch;
+ EFI_STATUS Status;
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF *StatementRef;
+
+ if (FormsetList == NULL || IS_EMPTY_STRING (Schema) ||
IS_EMPTY_STRING (Pattern) || StatementList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (RegularExpressionProtocol == NULL) {
+ return EFI_NOT_READY;
+ }
+
+ StatementList->Count = 0;
+ InitializeListHead (&StatementList->StatementList);
+
+ if (IsListEmpty (FormsetList)) {
+ return EFI_NOT_FOUND;
+ }
+
+ HiiFormsetLink = GetFirstNode (FormsetList);
+ while (!IsNull (FormsetList, HiiFormsetLink)) {
+ HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
+ HiiFormsetPrivate =
REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+ //
+ // Performance check.
+ // If there is no desired Redfish schema found, skip this formset.
+ //
+ if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema,
Schema)) {
+ HiiFormsetLink = HiiFormsetNextLink;
+ continue;
+ }
+
+ HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
+ while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
+ HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList,
HiiFormLink);
+ HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
(HiiFormLink);
+
+ HiiStatementLink =GetFirstNode (&HiiFormPrivate->StatementList);
+ while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
+ HiiNextStatementLink = GetNextNode (&HiiFormPrivate-
StatementList, HiiStatementLink);
+ HiiStatementPrivate =
REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
+
+ if (HiiStatementPrivate->Description != 0) {
+ TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle,
Schema, HiiStatementPrivate->Description);
+ if (TmpString != NULL) {
+ Status = RegularExpressionProtocol->MatchString (
+ RegularExpressionProtocol,
+ TmpString,
+ Pattern,
+ &gEfiRegexSyntaxTypePerlGuid,
+ &IsMatch,
+ NULL,
+ &CaptureCount
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, MatchString \"%s\" failed: %r\n",
__FUNCTION__, Pattern, Status));
+ ASSERT (FALSE);
+ return Status;
+ }
+
+ //
+ // Found
+ //
+ if (IsMatch) {
+ StatementRef = AllocateZeroPool (sizeof
(REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF));
+ if (StatementRef == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ StatementRef->Statement = HiiStatementPrivate;
+ InsertTailList (&StatementList->StatementList, &StatementRef-
Link);
+ ++StatementList->Count;
+ }
+
+ FreePool (TmpString);
+ }
+ }
+
+ HiiStatementLink = HiiNextStatementLink;
+ }
+
+ HiiFormLink = HiiNextFormLink;
+ }
+
+ HiiFormsetLink = HiiFormsetNextLink;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Get statement private instance by the given configure language.
+
+ @param[in] FormsetList Form-set list to search.
+ @param[in] Schema Schema to be matched.
+ @param[in] ConfigureLang Configure language.
+
+ @retval REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE * Pointer
to statement private instance.
+
+**/
+REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *
+GetStatementPrivateByConfigureLang (
+ IN LIST_ENTRY *FormsetList,
+ IN CHAR8 *Schema,
+ IN EFI_STRING ConfigureLang
+ )
+{
+ LIST_ENTRY *HiiFormsetLink;
+ LIST_ENTRY *HiiFormsetNextLink;
+ REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
+ LIST_ENTRY *HiiFormLink;
+ LIST_ENTRY *HiiNextFormLink;
+ REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate;
+ LIST_ENTRY *HiiStatementLink;
+ LIST_ENTRY *HiiNextStatementLink;
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
*HiiStatementPrivate;
+ EFI_STRING TmpString;
+
+ if (FormsetList == NULL || IS_EMPTY_STRING (Schema) ||
IS_EMPTY_STRING (ConfigureLang)) {
+ return NULL;
+ }
+
+ if (IsListEmpty (FormsetList)) {
+ return NULL;
+ }
+
+ HiiFormsetLink = GetFirstNode (FormsetList);
+ while (!IsNull (FormsetList, HiiFormsetLink)) {
+ HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
+ HiiFormsetPrivate =
REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+ //
+ // Performance check.
+ // If there is no desired Redfish schema found, skip this formset.
+ //
+ if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema,
Schema)) {
+ HiiFormsetLink = HiiFormsetNextLink;
+ continue;
+ }
+
+ HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
+ while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
+ HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList,
HiiFormLink);
+ HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
(HiiFormLink);
+
+ HiiStatementLink =GetFirstNode (&HiiFormPrivate->StatementList);
+ while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
+ HiiNextStatementLink = GetNextNode (&HiiFormPrivate-
StatementList, HiiStatementLink);
+ HiiStatementPrivate =
REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
+
+ DEBUG_CODE (
+ STATIC UINTN Index = 0;
+ DEBUG ((DEBUG_INFO, "%a, [%d] search %s in QID: 0x%x form: 0x%x
formset: %g\n", __FUNCTION__, ++Index, ConfigureLang,
HiiStatementPrivate->QuestionId, HiiFormPrivate->Id, &HiiFormsetPrivate-
Guid));
+ );
+
+ if (HiiStatementPrivate->Description != 0) {
+ TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle,
Schema, HiiStatementPrivate->Description);
+ if (TmpString != NULL) {
+ if (StrCmp (TmpString, ConfigureLang) == 0) {
+ FreePool (TmpString);
+ return HiiStatementPrivate;
+ }
+
+ FreePool (TmpString);
+ }
+ }
+
+ HiiStatementLink = HiiNextStatementLink;
+ }
+
+ HiiFormLink = HiiNextFormLink;
+ }
+
+ HiiFormsetLink = HiiFormsetNextLink;
+ }
+
+ return NULL;
+}
+
+/**
+ Get form-set private instance by the given HII handle.
+
+ @param[in] HiiHandle HII handle instance.
+ @param[in] FormsetList Form-set list to search.
+
+ @retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE * Pointer to
form-set private instance.
+
+**/
+REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *
+GetFormsetPrivateByHiiHandle (
+ IN EFI_HII_HANDLE HiiHandle,
+ IN LIST_ENTRY *FormsetList
+ )
+{
+ LIST_ENTRY *HiiFormsetLink;
+ LIST_ENTRY *HiiFormsetNextLink;
+ REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
+
+ if (HiiHandle == NULL || FormsetList == NULL) {
+ return NULL;
+ }
+
+ if (IsListEmpty (FormsetList)) {
+ return NULL;
+ }
+
+ HiiFormsetLink = GetFirstNode (FormsetList);
+ while (!IsNull (FormsetList, HiiFormsetLink)) {
+ HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
+ HiiFormsetPrivate =
REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+ if (HiiFormsetPrivate->HiiHandle == HiiHandle) {
+ return HiiFormsetPrivate;
+ }
+
+ HiiFormsetLink = HiiFormsetNextLink;
+ }
+
+ return NULL;
+}
+
+/**
+ Release formset and all the forms and statements that belong to this
formset.
+
+ @param[in] FormsetPrivate Pointer to HP_HII_FORM_SET_PRIVATE
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+ReleaseFormset (
+ IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate
+ )
+{
+ LIST_ENTRY *HiiFormLink;
+ LIST_ENTRY *HiiNextFormLink;
+ REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate;
+ LIST_ENTRY *HiiStatementLink;
+ LIST_ENTRY *HiiNextStatementLink;
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
*HiiStatementPrivate;
+ UINTN Index;
+
+ if (FormsetPrivate == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
+ while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
+ HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
(HiiFormLink);
+ HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList,
HiiFormLink);
+
+ HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
+ while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
+ HiiStatementPrivate =
REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
+ HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
HiiStatementLink);
+
+ //
+ // HiiStatementPrivate->HiiStatement will be released in
DestroyFormSet().
+ //
+
+ if (HiiStatementPrivate->DesStringCache != NULL) {
+ FreePool (HiiStatementPrivate->DesStringCache);
+ HiiStatementPrivate->DesStringCache = NULL;
+ }
+
+ RemoveEntryList (&HiiStatementPrivate->Link);
+ FreePool (HiiStatementPrivate);
+ HiiStatementLink = HiiNextStatementLink;
+ }
+
+ //
+ // HiiStatementPrivate->HiiForm will be released in DestroyFormSet().
+ //
+
+ RemoveEntryList (&HiiFormPrivate->Link);
+ FreePool (HiiFormPrivate);
+ HiiFormLink = HiiNextFormLink;
+ }
+
+ if (FormsetPrivate->HiiFormSet != NULL) {
+ DestroyFormSet (FormsetPrivate->HiiFormSet);
+ FormsetPrivate->HiiFormSet = NULL;
+ }
+
+ if (FormsetPrivate->DevicePathStr != NULL) {
+ FreePool(FormsetPrivate->DevicePathStr);
+ }
+
+ //
+ // Release schema list
+ //
+ if (FormsetPrivate->SupportedSchema.SchemaList != NULL) {
+ for (Index = 0; Index < FormsetPrivate->SupportedSchema.Count;
Index++) {
+ FreePool (FormsetPrivate->SupportedSchema.SchemaList[Index]);
+ }
+
+ FreePool (FormsetPrivate->SupportedSchema.SchemaList);
+ FormsetPrivate->SupportedSchema.SchemaList = NULL;
+ FormsetPrivate->SupportedSchema.Count = 0;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Create new form-set instance.
+
+ @retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE * Pointer to
newly created form-set private instance.
+
+**/
+REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *
+NewFormsetPrivate (
+ VOID
+ )
+{
+ REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *NewFormsetPrivate;
+
+ NewFormsetPrivate = AllocateZeroPool (sizeof
(REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE));
+ if (NewFormsetPrivate == NULL) {
+ return NULL;
+ }
+
+ //
+ // Initial newly created formset private data.
+ //
+ InitializeListHead (&NewFormsetPrivate->HiiFormList);
+
+ return NewFormsetPrivate;
+}
+
+/**
+ Load the HII formset from the given HII handle.
+
+ @param[in] HiiHandle Target HII handle to load.
+ @param[out] FormsetPrivate The formset private data.
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+LoadFormset (
+ IN EFI_HII_HANDLE HiiHandle,
+ OUT REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE
*FormsetPrivate
+ )
+{
+ EFI_STATUS Status;
+ HII_FORMSET *HiiFormSet;
+ HII_FORM *HiiForm;
+ LIST_ENTRY *HiiFormLink;
+ REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate;
+ HII_STATEMENT *HiiStatement;
+ LIST_ENTRY *HiiStatementLink;
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
*HiiStatementPrivate;
+ EFI_GUID ZeroGuid;
+
+ if (HiiHandle == NULL || FormsetPrivate == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+
+ HiiFormSet = AllocateZeroPool (sizeof (HII_FORMSET));
+ if (HiiFormSet == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Find HII formset by the given HII handle.
+ //
+ ZeroMem (&ZeroGuid, sizeof (ZeroGuid));
+ Status = CreateFormSetFromHiiHandle (HiiHandle, &ZeroGuid, HiiFormSet);
+ if (EFI_ERROR (Status) || IsListEmpty (&HiiFormSet->FormListHead)) {
+ Status = EFI_NOT_FOUND;
+ goto ErrorExit;
+ }
+
+ //
+ // Initialize formset
+ //
+ InitializeFormSet (HiiFormSet);
+
+ //
+ // Initialize formset private data.
+ //
+ FormsetPrivate->HiiFormSet = HiiFormSet;
+ FormsetPrivate->HiiHandle = HiiHandle;
+ CopyGuid (&FormsetPrivate->Guid, &HiiFormSet->Guid);
+ FormsetPrivate->DevicePathStr = ConvertDevicePathToText (HiiFormSet-
DevicePath, FALSE, FALSE);
+ Status = GetSupportedSchema (FormsetPrivate->HiiHandle,
&FormsetPrivate->SupportedSchema);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_WARN, "%a, No schema from HII handle: 0x%x found:
%r\n", __FUNCTION__, FormsetPrivate->HiiHandle, Status));
+ }
+
+ HiiFormLink = GetFirstNode (&HiiFormSet->FormListHead);
+ while (!IsNull (&HiiFormSet->FormListHead, HiiFormLink)) {
+ HiiForm = HII_FORM_FROM_LINK (HiiFormLink);
+
+ HiiFormPrivate = AllocateZeroPool (sizeof
(REDFISH_PLATFORM_CONFIG_FORM_PRIVATE));
+ if (HiiFormPrivate == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ErrorExit;
+ }
+
+ //
+ // Initialize form private data.
+ //
+ HiiFormPrivate->HiiForm = HiiForm;
+ HiiFormPrivate->Id = HiiForm->FormId;
+ HiiFormPrivate->Title = HiiForm->FormTitle;
+ HiiFormPrivate->ParentFormset = FormsetPrivate;
+ InitializeListHead (&HiiFormPrivate->StatementList);
+
+ HiiStatementLink = GetFirstNode (&HiiForm->StatementListHead);
+ while (!IsNull (&HiiForm->StatementListHead, HiiStatementLink)) {
+ HiiStatement = HII_STATEMENT_FROM_LINK (HiiStatementLink);
+
+ HiiStatementPrivate = AllocateZeroPool (sizeof
(REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE));
+ if (HiiStatementPrivate == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ErrorExit;
+ }
+ //
+ // Initialize statement private data.
+ //
+ HiiStatementPrivate->HiiStatement = HiiStatement;
+ HiiStatementPrivate->QuestionId = HiiStatement->QuestionId;
+ HiiStatementPrivate->Description = HiiStatement->Prompt;
+ HiiStatementPrivate->ParentForm = HiiFormPrivate;
+
+ //
+ // Attach to statement list.
+ //
+ InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate-
Link);
+ HiiStatementLink = GetNextNode (&HiiForm->StatementListHead,
HiiStatementLink);
+ }
+ //
+ // Attach to form list.
+ //
+ InsertTailList (&FormsetPrivate->HiiFormList, &HiiFormPrivate->Link);
+ HiiFormLink = GetNextNode (&HiiFormSet->FormListHead, HiiFormLink);
+ }
+
+ return EFI_SUCCESS;
+
+ErrorExit:
+
+ //
+ // Release HiiFormSet if HiiFormSet is not linked to FormsetPrivate yet.
+ //
+ if (HiiFormSet != NULL && FormsetPrivate->HiiFormSet != HiiFormSet) {
+ DestroyFormSet (HiiFormSet);
+ }
+
+ //
+ // Release resource when error happens.
+ //
+ ReleaseFormset (FormsetPrivate);
+
+ return Status;
+}
+
+/**
+ Release formset list and all the forms that belong to this formset.
+
+ @param[in] FormsetList Pointer to formst list that needs to be
+ released.
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+LoadFormsetList (
+ IN EFI_HII_HANDLE *HiiHandle,
+ OUT LIST_ENTRY *FormsetList
+ )
+{
+ EFI_STATUS Status;
+ REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate;
+
+ if (HiiHandle == NULL || FormsetList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FormsetPrivate = GetFormsetPrivateByHiiHandle (HiiHandle, FormsetList);
+ if (FormsetPrivate != NULL) {
+ return EFI_ALREADY_STARTED;
+ }
+
+ FormsetPrivate = NewFormsetPrivate ();
+ if (FormsetPrivate == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Load formset on the given HII handle.
+ //
+ Status = LoadFormset (HiiHandle, FormsetPrivate);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to load formset: %r\n",
__FUNCTION__, Status));
+ FreePool (FormsetPrivate);
+ return Status;
+ }
+
+ //
+ // Attach to cache list.
+ //
+ InsertTailList (FormsetList, &FormsetPrivate->Link);
+
+ DEBUG_CODE (
+ DumpFormsetList (FormsetList);
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Release formset list and all the forms that belong to this formset.
+
+ @param[in] FormsetList Pointer to formst list that needs to be
+ released.
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+ReleaseFormsetList (
+ IN LIST_ENTRY *FormsetList
+ )
+{
+ LIST_ENTRY *HiiFormsetLink;
+ LIST_ENTRY *HiiFormsetNextLink;
+ REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
+
+ if (FormsetList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (IsListEmpty (FormsetList)) {
+ return EFI_SUCCESS;
+ }
+
+ HiiFormsetLink = GetFirstNode (FormsetList);
+ while (!IsNull (FormsetList, HiiFormsetLink)) {
+ HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
+ HiiFormsetPrivate =
REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+ //
+ // Detach from list.
+ //
+ RemoveEntryList (&HiiFormsetPrivate->Link);
+ ReleaseFormset (HiiFormsetPrivate);
+ FreePool (HiiFormsetPrivate);
+ HiiFormsetLink = HiiFormsetNextLink;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Get all pending list.
+
+ @param[in] HiiHandle HII handle instance.
+ @param[in] PendingList Pending list to keep pending data.
+
+ @retval REDFISH_PLATFORM_CONFIG_PENDING_LIST * Pointer to
pending list data.
+
+**/
+REDFISH_PLATFORM_CONFIG_PENDING_LIST *
+GetPendingList (
+ IN EFI_HII_HANDLE *HiiHandle,
+ IN LIST_ENTRY *PendingList
+ )
+{
+ LIST_ENTRY *PendingListLink;
+ REDFISH_PLATFORM_CONFIG_PENDING_LIST *Target;
+
+ if (HiiHandle == NULL || PendingList == NULL) {
+ return NULL;
+ }
+
+ if (IsListEmpty (PendingList)) {
+ return NULL;
+ }
+
+ PendingListLink = GetFirstNode (PendingList);
+ while (!IsNull (PendingList, PendingListLink)) {
+ Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK
(PendingListLink);
+
+ if (Target->HiiHandle == HiiHandle) {
+ return Target;
+ }
+
+ PendingListLink = GetNextNode (PendingList, PendingListLink);
+ }
+
+ return NULL;
+}
+
+/**
+ When HII database is updated. Keep updated HII handle into pending list
so
+ we can process them later.
+
+ @param[in] HiiHandle HII handle instance.
+ @param[in] PendingList Pending list to keep HII handle which is recently
updated.
+
+ @retval EFI_SUCCESS HII handle is saved in pending list.
+ @retval EFI_INVALID_PARAMETER HiiHnalde is NULL or PendingList is
NULL.
+ @retval EFI_OUT_OF_RESOURCES System is out of memory.
+
+**/
+EFI_STATUS
+NotifyFormsetUpdate (
+ IN EFI_HII_HANDLE *HiiHandle,
+ IN LIST_ENTRY *PendingList
+ )
+{
+ REDFISH_PLATFORM_CONFIG_PENDING_LIST *TargetPendingList;
+
+ if (HiiHandle == NULL || PendingList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check and see if this HII handle is processed already.
+ //
+ TargetPendingList = GetPendingList (HiiHandle, PendingList);
+ if (TargetPendingList != NULL) {
+ TargetPendingList->IsDeleted = FALSE;
+ DEBUG_CODE (
+ DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated\n",
__FUNCTION__, HiiHandle));
+ );
+ return EFI_SUCCESS;
+ }
+
+ TargetPendingList= AllocateZeroPool (sizeof
(REDFISH_PLATFORM_CONFIG_PENDING_LIST));
+ if (TargetPendingList == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ TargetPendingList->HiiHandle = HiiHandle;
+ TargetPendingList->IsDeleted = FALSE;
+
+ InsertTailList (PendingList, &TargetPendingList->Link);
+
+ DEBUG_CODE (
+ DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is created\n",
__FUNCTION__, HiiHandle));
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ When HII database is updated and form-set is deleted. Keep deleted HII
handle into pending list so
+ we can process them later.
+
+ @param[in] HiiHandle HII handle instance.
+ @param[in] PendingList Pending list to keep HII handle which is recently
updated.
+
+ @retval EFI_SUCCESS HII handle is saved in pending list.
+ @retval EFI_INVALID_PARAMETER HiiHnalde is NULL or PendingList is
NULL.
+ @retval EFI_OUT_OF_RESOURCES System is out of memory.
+
+**/
+EFI_STATUS
+NotifyFormsetDeleted (
+ IN EFI_HII_HANDLE *HiiHandle,
+ IN LIST_ENTRY *PendingList
+ )
+{
+ REDFISH_PLATFORM_CONFIG_PENDING_LIST *TargetPendingList;
+
+ if (HiiHandle == NULL || PendingList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check and see if this HII handle is processed already.
+ //
+ TargetPendingList = GetPendingList (HiiHandle, PendingList);
+ if (TargetPendingList != NULL) {
+ TargetPendingList->IsDeleted = TRUE;
+ DEBUG_CODE (
+ DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated and deleted\n",
__FUNCTION__, HiiHandle));
+ );
+ return EFI_SUCCESS;
+ }
+
+ TargetPendingList= AllocateZeroPool (sizeof
(REDFISH_PLATFORM_CONFIG_PENDING_LIST));
+ if (TargetPendingList == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ TargetPendingList->HiiHandle = HiiHandle;
+ TargetPendingList->IsDeleted = TRUE;
+
+ InsertTailList (PendingList, &TargetPendingList->Link);
+
+ DEBUG_CODE (
+ DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is deleted\n",
__FUNCTION__, HiiHandle));
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ There are HII database update and we need to process them accordingly
so that we
+ won't use stale data. This function will parse updated HII handle again in
order
+ to get updated data-set.
+
+ @param[in] FormsetList List to keep HII form-set.
+ @param[in] PendingList List to keep HII handle that is updated.
+
+ @retval EFI_SUCCESS HII handle is saved in pending list.
+ @retval EFI_INVALID_PARAMETER FormsetList is NULL or PendingList is
NULL.
+
+**/
+EFI_STATUS
+ProcessPendingList (
+ IN LIST_ENTRY *FormsetList,
+ IN LIST_ENTRY *PendingList
+ )
+{
+ LIST_ENTRY *PendingListLink;
+ LIST_ENTRY *PendingListNextLink;
+ REDFISH_PLATFORM_CONFIG_PENDING_LIST *Target;
+ REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate;
+ EFI_STATUS Status;
+
+
+ if (FormsetList == NULL || PendingList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (IsListEmpty (PendingList)) {
+ return EFI_SUCCESS;
+ }
+
+ PendingListLink = GetFirstNode (PendingList);
+ while (!IsNull (PendingList, PendingListLink)) {
+ PendingListNextLink = GetNextNode (PendingList, PendingListLink);
+ Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK
(PendingListLink);
+
+ if (Target->IsDeleted) {
+ //
+ // The HII resource on this HII handle is removed. Release the formset.
+ //
+ FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle,
FormsetList);
+ if (FormsetPrivate != NULL) {
+ DEBUG ((DEBUG_INFO, "%a, formset: %g is removed because driver
release HII resource it already\n", __FUNCTION__, FormsetPrivate->Guid));
+ RemoveEntryList (&FormsetPrivate->Link);
+ ReleaseFormset (FormsetPrivate);
+ FreePool (FormsetPrivate);
+ } else {
+ DEBUG ((DEBUG_WARN, "%a, formset on HII handle 0x%x was
removed already\n", __FUNCTION__, Target->HiiHandle));
+ }
+ } else {
+ //
+ // The HII resource on this HII handle is updated/removed.
+ //
+ FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle,
FormsetList);
+ if (FormsetPrivate != NULL) {
+ //
+ // HII formset already exist, release it and query again.
+ //
+ DEBUG ((DEBUG_INFO, "%a, formset: %g is updated. Release current
formset\n", __FUNCTION__, &FormsetPrivate->Guid));
+ RemoveEntryList (&FormsetPrivate->Link);
+ ReleaseFormset (FormsetPrivate);
+ FreePool (FormsetPrivate);
+ }
+
+ Status = LoadFormsetList (Target->HiiHandle, FormsetList);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, load formset from HII handle: 0x%x
failed: %r\n", __FUNCTION__, Target->HiiHandle, Status));
+ }
+ }
+
+ //
+ // Detach it from list first.
+ //
+ RemoveEntryList (&Target->Link);
+ FreePool (Target);
+
+ PendingListLink = PendingListNextLink;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Release all resource in statement list.
+
+ @param[in] StatementList Statement list to be released.
+
+ @retval EFI_SUCCESS All resource are released.
+ @retval EFI_INVALID_PARAMETER StatementList is NULL.
+
+**/
+EFI_STATUS
+ReleaseStatementList (
+ IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
*StatementList
+ )
+{
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF *StatementRef;
+ LIST_ENTRY *NextLink;
+
+ if (StatementList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (IsListEmpty (&StatementList->StatementList)) {
+ return EFI_SUCCESS;
+ }
+
+ NextLink = GetFirstNode (&StatementList->StatementList);
+ while (!IsNull (&StatementList->StatementList, NextLink)) {
+ StatementRef =
REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
+ NextLink = GetNextNode (&StatementList->StatementList, NextLink);
+
+ RemoveEntryList (&StatementRef->Link);
+ FreePool (StatementRef);
+ }
+
+ return EFI_SUCCESS;
+}
diff --git
a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
index e0ba0fb2d3..be2f63df8d 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
@@ -1,274 +1,297 @@
-/** @file
- This file defines the EDKII Redfish Platform Config Protocol interface.
-
- (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_
-#define EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_
-
-#include <Uefi.h>
-
-//
-// Libraries
-//
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/DevicePathLib.h>
-#include <Library/HiiUtilityLib.h>
-#include <Library/HiiLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiLib.h>
-
-#define REDFISH_PLATFORM_CONFIG_DELETE_EXPIRED_FORMSET 0x00
-#define IS_EMPTY_STRING(a) (a == NULL || a[0] == L'\0')
-#define ENGLISH_LANGUAGE_CODE "en-US"
-#define X_UEFI_SCHEMA_PREFIX "x-uefi-redfish-"
-
-//
-// Definition of REDFISH_PLATFORM_CONFIG_PRIVATE.
-//
-typedef struct {
- LIST_ENTRY Link;
- EFI_HII_HANDLE HiiHandle;
- BOOLEAN IsDeleted;
-} REDFISH_PLATFORM_CONFIG_PENDING_LIST;
-
-#define REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK(a)
BASE_CR (a, REDFISH_PLATFORM_CONFIG_PENDING_LIST, Link)
-
-typedef struct {
- UINTN Count; // Number of schema in list
- CHAR8 **SchemaList; // Schema list
-} REDFISH_PLATFORM_CONFIG_SCHEMA;
-
-//
-// Definition of REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE
-//
-typedef struct {
- LIST_ENTRY Link;
- HII_FORMSET *HiiFormSet; // Pointer to HII formset data.
- EFI_GUID Guid; // Formset GUID.
- EFI_HII_HANDLE HiiHandle; // Hii Handle of this formset.
- LIST_ENTRY HiiFormList; // Form list that keep form data under
this formset.
- CHAR16 *DevicePathStr; // Device path of this formset.
- REDFISH_PLATFORM_CONFIG_SCHEMA SupportedSchema; // Schema
that is supported in this formset.
-} REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE;
-
-#define REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK(a) BASE_CR
(a, REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE, Link)
-
-//
-// Definition of REDFISH_PLATFORM_CONFIG_FORM_PRIVATE
-//
-typedef struct {
- LIST_ENTRY Link;
- UINT16 Id; // Form ID.
- EFI_STRING_ID Title; // String token of form title.
- REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *ParentFormset;
- HII_FORM *HiiForm; // Pointer to HII form data.
- LIST_ENTRY StatementList; // Statement list that keep
statement under this form.
-} REDFISH_PLATFORM_CONFIG_FORM_PRIVATE;
-
-#define REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK(a) BASE_CR (a,
REDFISH_PLATFORM_CONFIG_FORM_PRIVATE, Link)
-
-//
-// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
-//
-typedef struct {
- LIST_ENTRY Link;
- REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *ParentForm;
- HII_STATEMENT *HiiStatement; // Pointer to HII statement
data.
- EFI_QUESTION_ID QuestionId; // Question ID of this
statement.
- EFI_STRING_ID Description; // String token of this question.
- EFI_STRING DesStringCache; // The string cache for search
function.
-} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE;
-
-#define REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK(a)
BASE_CR (a, REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE, Link)
-
-//
-// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF
-//
-typedef struct {
- LIST_ENTRY Link;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement;
-} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF;
-
-#define REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK(a)
BASE_CR (a, REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF, Link)
-
-//
-// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
-//
-typedef struct {
- LIST_ENTRY StatementList; // List of
REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF
- UINTN Count;
-} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST;
-
-/**
- Release formset list and all the forms that belong to this formset.
-
- @param[in] FormsetList Pointer to formst list that needs to be
- released.
-
- @retval EFI_STATUS
-
-**/
-EFI_STATUS
-ReleaseFormsetList (
- IN LIST_ENTRY *FormsetList
- );
-
-/**
- Release formset list and all the forms that belong to this formset.
-
- @param[in] FormsetList Pointer to formst list that needs to be
- released.
-
- @retval EFI_STATUS
-
-**/
-EFI_STATUS
-LoadFormsetList (
- IN EFI_HII_HANDLE *HiiHandle,
- OUT LIST_ENTRY *FormsetList
- );
-
-/**
- When HII database is updated. Keep updated HII handle into pending list so
- we can process them later.
-
- @param[in] HiiHandle HII handle instance.
- @param[in] PendingList Pending list to keep HII handle which is recently
updated.
-
- @retval EFI_SUCCESS HII handle is saved in pending list.
- @retval EFI_INVALID_PARAMETER HiiHnalde is NULL or PendingList is
NULL.
- @retval EFI_OUT_OF_RESOURCES System is out of memory.
-
-**/
-EFI_STATUS
-NotifyFormsetUpdate (
- IN EFI_HII_HANDLE *HiiHandle,
- IN LIST_ENTRY *PendingList
- );
-
-/**
- When HII database is updated and form-set is deleted. Keep deleted HII
handle into pending list so
- we can process them later.
-
- @param[in] HiiHandle HII handle instance.
- @param[in] PendingList Pending list to keep HII handle which is recently
updated.
-
- @retval EFI_SUCCESS HII handle is saved in pending list.
- @retval EFI_INVALID_PARAMETER HiiHnalde is NULL or PendingList is
NULL.
- @retval EFI_OUT_OF_RESOURCES System is out of memory.
-
-**/
-EFI_STATUS
-NotifyFormsetDeleted (
- IN EFI_HII_HANDLE *HiiHandle,
- IN LIST_ENTRY *PendingList
- );
-
-/**
- Get statement private instance by the given configure language.
-
- @param[in] FormsetList Form-set list to search.
- @param[in] Schema Schema to be matched.
- @param[in] ConfigureLang Configure language.
-
- @retval REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE * Pointer to
statement private instance.
-
-**/
-REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *
-GetStatementPrivateByConfigureLang (
- IN LIST_ENTRY *FormsetList,
- IN CHAR8 *Schema,
- IN EFI_STRING ConfigureLang
- );
-
-/**
- Search and find statement private instance by given regular expression
patthern
- which describes the Configure Language.
-
- @param[in] RegularExpressionProtocol Regular express protocol.
- @param[in] FormsetList Form-set list to search.
- @param[in] Schema Schema to be matched.
- @param[in] Pattern Regular expression pattern.
- @param[out] StatementList Statement list that match above
pattern.
-
- @retval EFI_SUCCESS Statement list is returned.
- @retval EFI_INVALID_PARAMETER Input parameter is NULL.
- @retval EFI_NOT_READY Regular express protocol is NULL.
- @retval EFI_NOT_FOUND No statement is found.
- @retval EFI_OUT_OF_RESOURCES System is out of memory.
-
-**/
-EFI_STATUS
-GetStatementPrivateByConfigureLangRegex (
- IN EFI_REGULAR_EXPRESSION_PROTOCOL
*RegularExpressionProtocol,
- IN LIST_ENTRY *FormsetList,
- IN CHAR8 *Schema,
- IN EFI_STRING Pattern,
- OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
*StatementList
- );
-
-/**
- There are HII database update and we need to process them accordingly so
that we
- won't use stale data. This function will parse updated HII handle again in
order
- to get updated data-set.
-
- @param[in] FormsetList List to keep HII form-set.
- @param[in] PendingList List to keep HII handle that is updated.
-
- @retval EFI_SUCCESS HII handle is saved in pending list.
- @retval EFI_INVALID_PARAMETER FormsetList is NULL or PendingList is
NULL.
-
-**/
-EFI_STATUS
-ProcessPendingList (
- IN LIST_ENTRY *FormsetList,
- IN LIST_ENTRY *PendingList
- );
-
-/**
- Retrieves a string from a string package in a English language. The
- returned string is allocated using AllocatePool(). The caller is responsible
- for freeing the allocated buffer using FreePool().
-
- If HiiHandle is NULL, then ASSERT().
- If StringId is 0, then ASSET.
-
- @param[in] HiiStringProtocol EFI_HII_STRING_PROTOCOL instance.
- @param[in] HiiHandle A handle that was previously registered in the
HII Database.
- @param[in] StringId The identifier of the string to retrieved from the
string
- package associated with HiiHandle.
-
- @retval NULL The string specified by StringId is not present in the string
package.
- @retval Other The string was returned.
-
-**/
-EFI_STRING
-HiiGetRedfishString (
- IN EFI_HII_HANDLE HiiHandle,
- IN CHAR8 *Language,
- IN EFI_STRING_ID StringId
- );
-
-/**
- Release all resource in statement list.
-
- @param[in] StatementList Statement list to be released.
-
- @retval EFI_SUCCESS All resource are released.
- @retval EFI_INVALID_PARAMETER StatementList is NULL.
-
-**/
-EFI_STATUS
-ReleaseStatementList (
- IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
*StatementList
- );
-
-#endif
+/** @file
+ This file defines the EDKII Redfish Platform Config Protocol interface.
+
+ (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_
+#define EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_
+
+#include <Uefi.h>
+
+//
+// Libraries
+//
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiUtilityLib.h>
+#include <Library/HiiLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+#define IS_EMPTY_STRING(a) (a == NULL || a[0] == L'\0')
+#define ENGLISH_LANGUAGE_CODE "en-US"
+#define X_UEFI_SCHEMA_PREFIX "x-uefi-redfish-"
+
+//
+// Definition of REDFISH_PLATFORM_CONFIG_PRIVATE.
+//
+typedef struct {
+ LIST_ENTRY Link;
+ EFI_HII_HANDLE HiiHandle;
+ BOOLEAN IsDeleted;
+} REDFISH_PLATFORM_CONFIG_PENDING_LIST;
+
+#define REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK(a)
BASE_CR (a, REDFISH_PLATFORM_CONFIG_PENDING_LIST, Link)
+
+typedef struct {
+ UINTN Count; // Number of schema in list
+ CHAR8 **SchemaList; // Schema list
+} REDFISH_PLATFORM_CONFIG_SCHEMA;
+
+//
+// Definition of REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE
+//
+typedef struct {
+ LIST_ENTRY Link;
+ HII_FORMSET *HiiFormSet; // Pointer to HII formset data.
+ EFI_GUID Guid; // Formset GUID.
+ EFI_HII_HANDLE HiiHandle; // Hii Handle of this formset.
+ LIST_ENTRY HiiFormList; // Form list that keep form data under
this formset.
+ CHAR16 *DevicePathStr; // Device path of this formset.
+ REDFISH_PLATFORM_CONFIG_SCHEMA SupportedSchema; // Schema
that is supported in this formset.
+} REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE;
+
+#define REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK(a) BASE_CR
(a, REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE, Link)
+
+//
+// Definition of REDFISH_PLATFORM_CONFIG_FORM_PRIVATE
+//
+typedef struct {
+ LIST_ENTRY Link;
+ UINT16 Id; // Form ID.
+ EFI_STRING_ID Title; // String token of form title.
+ REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *ParentFormset;
+ HII_FORM *HiiForm; // Pointer to HII form data.
+ LIST_ENTRY StatementList; // Statement list that keep
statement under this form.
+} REDFISH_PLATFORM_CONFIG_FORM_PRIVATE;
+
+#define REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK(a) BASE_CR (a,
REDFISH_PLATFORM_CONFIG_FORM_PRIVATE, Link)
+
+//
+// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
+//
+typedef struct {
+ LIST_ENTRY Link;
+ REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *ParentForm;
+ HII_STATEMENT *HiiStatement; // Pointer to HII statement
data.
+ EFI_QUESTION_ID QuestionId; // Question ID of this
statement.
+ EFI_STRING_ID Description; // String token of this question.
+ EFI_STRING DesStringCache; // The string cache for search
function.
+} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE;
+
+#define REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK(a)
BASE_CR (a, REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE, Link)
+
+//
+// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF
+//
+typedef struct {
+ LIST_ENTRY Link;
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement;
+} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF;
+
+#define REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK(a)
BASE_CR (a, REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF, Link)
+
+//
+// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
+//
+typedef struct {
+ LIST_ENTRY StatementList; // List of
REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF
+ UINTN Count;
+} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST;
+
+/**
+ Release formset list and all the forms that belong to this formset.
+
+ @param[in] FormsetList Pointer to formst list that needs to be
+ released.
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+ReleaseFormsetList (
+ IN LIST_ENTRY *FormsetList
+ );
+
+/**
+ Release formset list and all the forms that belong to this formset.
+
+ @param[in] FormsetList Pointer to formst list that needs to be
+ released.
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+LoadFormsetList (
+ IN EFI_HII_HANDLE *HiiHandle,
+ OUT LIST_ENTRY *FormsetList
+ );
+
+/**
+ When HII database is updated. Keep updated HII handle into pending list
so
+ we can process them later.
+
+ @param[in] HiiHandle HII handle instance.
+ @param[in] PendingList Pending list to keep HII handle which is recently
updated.
+
+ @retval EFI_SUCCESS HII handle is saved in pending list.
+ @retval EFI_INVALID_PARAMETER HiiHnalde is NULL or PendingList is
NULL.
+ @retval EFI_OUT_OF_RESOURCES System is out of memory.
+
+**/
+EFI_STATUS
+NotifyFormsetUpdate (
+ IN EFI_HII_HANDLE *HiiHandle,
+ IN LIST_ENTRY *PendingList
+ );
+
+/**
+ When HII database is updated and form-set is deleted. Keep deleted HII
handle into pending list so
+ we can process them later.
+
+ @param[in] HiiHandle HII handle instance.
+ @param[in] PendingList Pending list to keep HII handle which is recently
updated.
+
+ @retval EFI_SUCCESS HII handle is saved in pending list.
+ @retval EFI_INVALID_PARAMETER HiiHnalde is NULL or PendingList is
NULL.
+ @retval EFI_OUT_OF_RESOURCES System is out of memory.
+
+**/
+EFI_STATUS
+NotifyFormsetDeleted (
+ IN EFI_HII_HANDLE *HiiHandle,
+ IN LIST_ENTRY *PendingList
+ );
+
+/**
+ Get statement private instance by the given configure language.
+
+ @param[in] FormsetList Form-set list to search.
+ @param[in] Schema Schema to be matched.
+ @param[in] ConfigureLang Configure language.
+
+ @retval REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE * Pointer
to statement private instance.
+
+**/
+REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *
+GetStatementPrivateByConfigureLang (
+ IN LIST_ENTRY *FormsetList,
+ IN CHAR8 *Schema,
+ IN EFI_STRING ConfigureLang
+ );
+
+/**
+ Search and find statement private instance by given regular expression
patthern
+ which describes the Configure Language.
+
+ @param[in] RegularExpressionProtocol Regular express protocol.
+ @param[in] FormsetList Form-set list to search.
+ @param[in] Schema Schema to be matched.
+ @param[in] Pattern Regular expression pattern.
+ @param[out] StatementList Statement list that match above
pattern.
+
+ @retval EFI_SUCCESS Statement list is returned.
+ @retval EFI_INVALID_PARAMETER Input parameter is NULL.
+ @retval EFI_NOT_READY Regular express protocol is NULL.
+ @retval EFI_NOT_FOUND No statement is found.
+ @retval EFI_OUT_OF_RESOURCES System is out of memory.
+
+**/
+EFI_STATUS
+GetStatementPrivateByConfigureLangRegex (
+ IN EFI_REGULAR_EXPRESSION_PROTOCOL
*RegularExpressionProtocol,
+ IN LIST_ENTRY *FormsetList,
+ IN CHAR8 *Schema,
+ IN EFI_STRING Pattern,
+ OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
*StatementList
+ );
+
+/**
+ There are HII database update and we need to process them accordingly
so that we
+ won't use stale data. This function will parse updated HII handle again in
order
+ to get updated data-set.
+
+ @param[in] FormsetList List to keep HII form-set.
+ @param[in] PendingList List to keep HII handle that is updated.
+
+ @retval EFI_SUCCESS HII handle is saved in pending list.
+ @retval EFI_INVALID_PARAMETER FormsetList is NULL or PendingList is
NULL.
+
+**/
+EFI_STATUS
+ProcessPendingList (
+ IN LIST_ENTRY *FormsetList,
+ IN LIST_ENTRY *PendingList
+ );
+
+/**
+ Retrieves a string from a string package in a English language. The
+ returned string is allocated using AllocatePool(). The caller is responsible
+ for freeing the allocated buffer using FreePool().
+
+ If HiiHandle is NULL, then ASSERT().
+ If StringId is 0, then ASSET.
+
+ @param[in] HiiStringProtocol EFI_HII_STRING_PROTOCOL instance.
+ @param[in] HiiHandle A handle that was previously registered in the
HII Database.
+ @param[in] StringId The identifier of the string to retrieved from the
string
+ package associated with HiiHandle.
+
+ @retval NULL The string specified by StringId is not present in the string
package.
+ @retval Other The string was returned.
+
+**/
+EFI_STRING
+HiiGetRedfishString (
+ IN EFI_HII_HANDLE HiiHandle,
+ IN CHAR8 *Language,
+ IN EFI_STRING_ID StringId
+ );
+
+/**
+ Retrieves a string from a string package in a English language. The
+ returned string is allocated using AllocatePool(). The caller is responsible
+ for freeing the allocated buffer using FreePool().
+
+ If HiiHandle is NULL, then ASSERT().
+ If StringId is 0, then ASSET.
+
+ @param[in] HiiStringProtocol EFI_HII_STRING_PROTOCOL instance.
+ @param[in] HiiHandle A handle that was previously registered in the
HII Database.
+ @param[in] StringId The identifier of the string to retrieved from the
string
The function parameters are not correct.

Thanks
Abner

+ package associated with HiiHandle.
+
+ @retval NULL The string specified by StringId is not present in the string
package.
+ @retval Other The string was returned.
+
+**/
+CHAR8 *
+HiiGetRedfishAsciiString (
+ IN EFI_HII_HANDLE HiiHandle,
+ IN CHAR8 *Language,
+ IN EFI_STRING_ID StringId
+ );
+
+/**
+ Release all resource in statement list.
+
+ @param[in] StatementList Statement list to be released.
+
+ @retval EFI_SUCCESS All resource are released.
+ @retval EFI_INVALID_PARAMETER StatementList is NULL.
+
+**/
+EFI_STATUS
+ReleaseStatementList (
+ IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
*StatementList
+ );
+
+#endif
--
2.32.0.windows.2


[edk2-staging][PATCH v3] edk2/RedfishPkg: Update Redfish Platform Config Protocol

Nickle Wang
 

Update EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL and add array type of
value support to EDKII_REDFISH_VALUE in order to support ordered list
op-code in HII. Modify corresponding function to support new type of
data structure.

Signed-off-by: Nickle Wang <nickle.wang@...>
Cc: Abner Chang <abner.chang@...>
Cc: Yang Atom <Atom.Yang@...>
Cc: Nick Ramirez <nramirez@...>
---
.../Protocol/EdkIIRedfishPlatformConfig.h | 301 +-
.../RedfishPlatformConfigDxe.c | 3087 ++++++++++-------
.../RedfishPlatformConfigDxe.h | 128 +-
.../RedfishPlatformConfigDxe.inf | 104 +-
.../RedfishPlatformConfigImpl.c | 2528 +++++++-------
.../RedfishPlatformConfigImpl.h | 571 +--
6 files changed, 3638 insertions(+), 3081 deletions(-)

diff --git a/RedfishPkg/Include/Protocol/EdkIIRedfishPlatformConfig.h b/RedfishPkg/Include/Protocol/EdkIIRedfishPlatformConfig.h
index 895b010227..bbbab90b03 100644
--- a/RedfishPkg/Include/Protocol/EdkIIRedfishPlatformConfig.h
+++ b/RedfishPkg/Include/Protocol/EdkIIRedfishPlatformConfig.h
@@ -1,147 +1,154 @@
-/** @file
- This file defines the EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL interface.
-
- (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef EDKII_REDFISH_PLATFORM_CONFIG_H_
-#define EDKII_REDFISH_PLATFORM_CONFIG_H_
-
-typedef struct _EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL;
-
-/**
- Definition of EDKII_REDFISH_TYPE_VALUE
- **/
-typedef union {
- INT64 Integer;
- BOOLEAN Boolean;
- CHAR8 *Buffer;
-} EDKII_REDFISH_TYPE_VALUE;
-
-/**
- Definition of EDKII_REDFISH_VALUE_TYPES
- **/
-typedef enum {
- REDFISH_VALUE_TYPE_UNKNOWN = 0,
- REDFISH_VALUE_TYPE_INTEGER,
- REDFISH_VALUE_TYPE_BOOLEAN,
- REDFISH_VALUE_TYPE_STRING,
- REDFISH_VALUE_TYPE_MAX
-} EDKII_REDFISH_VALUE_TYPES;
-
-/**
- Definition of EDKII_REDFISH_VALUE
- **/
-typedef struct {
- EDKII_REDFISH_VALUE_TYPES Type;
- EDKII_REDFISH_TYPE_VALUE Value;
-} EDKII_REDFISH_VALUE;
-
-/**
- Get Redfish value with the given Schema and Configure Language.
-
- @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
- @param[in] Schema The Redfish schema to query.
- @param[in] Version The Redfish version to query.
- @param[in] ConfigureLang The target value which match this configure Language.
- @param[out] Value The returned value.
-
- @retval EFI_SUCCESS Value is returned successfully.
- @retval Others Some error happened.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_VALUE) (
- IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
- IN CHAR8 *Schema,
- IN CHAR8 *Version,
- IN EFI_STRING ConfigureLang,
- OUT EDKII_REDFISH_VALUE *Value
- );
-
-/**
- Set Redfish value with the given Schema and Configure Language.
-
- @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
- @param[in] Schema The Redfish schema to query.
- @param[in] Version The Redfish version to query.
- @param[in] ConfigureLang The target value which match this configure Language.
- @param[in] Value The value to set.
-
- @retval EFI_SUCCESS Value is returned successfully.
- @retval Others Some error happened.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_SET_VALUE) (
- IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
- IN CHAR8 *Schema,
- IN CHAR8 *Version,
- IN EFI_STRING ConfigureLang,
- IN EDKII_REDFISH_VALUE Value
- );
-
-/**
- Get the list of Configure Language from platform configuration by the given Schema and Pattern.
-
- @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
- @param[in] Schema The Redfish schema to query.
- @param[in] Version The Redfish version to query.
- @param[in] Pattern The target Configure Language pattern.
- @param[out] ConfigureLangList The list of Configure Language.
- @param[out] Count The number of Configure Language in ConfigureLangList.
-
- @retval EFI_SUCCESS ConfigureLangList is returned successfully.
- @retval Others Some error happened.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_CONFIG_LANG) (
- IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
- IN CHAR8 *Schema,
- IN CHAR8 *Version,
- IN EFI_STRING Pattern,
- OUT EFI_STRING **ConfigureLangList,
- OUT UINTN *Count
- );
-
-
-/**
- Get the list of supported Redfish schema from platform configuration on the give HII handle.
-
- @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
- @param[in] HiiHandle The target handle to search. If handle is NULL,
- this function returns all schema from HII database.
- @param[out] SupportedSchema The supported schema list which is separated by ';'.
- For example: "x-uefi-redfish-Memory.v1_7_1;x-uefi-redfish-Boot.v1_0_1"
- The SupportedSchema is allocated by the callee. It's caller's
- responsibility to free this buffer using FreePool().
-
- @retval EFI_SUCCESS Schema is returned successfully.
- @retval Others Some error happened.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_SUPPORTED_SCHEMA) (
- IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
- IN EFI_HII_HANDLE HiiHandle, OPTIONAL
- OUT CHAR8 **SupportedSchema
- );
-
-struct _EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL {
- EDKII_REDFISH_PLATFORM_CONFIG_GET_VALUE GetValue;
- EDKII_REDFISH_PLATFORM_CONFIG_SET_VALUE SetValue;
- EDKII_REDFISH_PLATFORM_CONFIG_GET_CONFIG_LANG GetConfigureLang;
- EDKII_REDFISH_PLATFORM_CONFIG_GET_SUPPORTED_SCHEMA GetSupportedSchema;
-};
-
-extern EFI_GUID gEdkIIRedfishPlatformConfigProtocolGuid;
-
-#endif
+/** @file
+ This file defines the EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL interface.
+
+ (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef EDKII_REDFISH_PLATFORM_CONFIG_H_
+#define EDKII_REDFISH_PLATFORM_CONFIG_H_
+
+typedef struct _EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL;
+
+/**
+ Definition of EDKII_REDFISH_TYPE_VALUE
+ **/
+typedef union {
+ INT64 Integer;
+ BOOLEAN Boolean;
+ CHAR8 *Buffer;
+ CHAR8 **StringArray;
+ INT64 *IntegerArray;
+ BOOLEAN *BooleanArray;
+} EDKII_REDFISH_TYPE_VALUE;
+
+/**
+ Definition of EDKII_REDFISH_VALUE_TYPES
+ **/
+typedef enum {
+ REDFISH_VALUE_TYPE_UNKNOWN = 0,
+ REDFISH_VALUE_TYPE_INTEGER,
+ REDFISH_VALUE_TYPE_BOOLEAN,
+ REDFISH_VALUE_TYPE_STRING,
+ REDFISH_VALUE_TYPE_STRING_ARRAY,
+ REDFISH_VALUE_TYPE_INTEGER_ARRAY,
+ REDFISH_VALUE_TYPE_BOOLEAN_ARRAY,
+ REDFISH_VALUE_TYPE_MAX
+} EDKII_REDFISH_VALUE_TYPES;
+
+/**
+ Definition of EDKII_REDFISH_VALUE
+ **/
+typedef struct {
+ EDKII_REDFISH_VALUE_TYPES Type;
+ EDKII_REDFISH_TYPE_VALUE Value;
+ UINTN ArrayCount;
+} EDKII_REDFISH_VALUE;
+
+/**
+ Get Redfish value with the given Schema and Configure Language.
+
+ @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+ @param[in] Schema The Redfish schema to query.
+ @param[in] Version The Redfish version to query.
+ @param[in] ConfigureLang The target value which match this configure Language.
+ @param[out] Value The returned value.
+
+ @retval EFI_SUCCESS Value is returned successfully.
+ @retval Others Some error happened.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_VALUE) (
+ IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+ IN CHAR8 *Schema,
+ IN CHAR8 *Version,
+ IN EFI_STRING ConfigureLang,
+ OUT EDKII_REDFISH_VALUE *Value
+ );
+
+/**
+ Set Redfish value with the given Schema and Configure Language.
+
+ @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+ @param[in] Schema The Redfish schema to query.
+ @param[in] Version The Redfish version to query.
+ @param[in] ConfigureLang The target value which match this configure Language.
+ @param[in] Value The value to set.
+
+ @retval EFI_SUCCESS Value is returned successfully.
+ @retval Others Some error happened.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_SET_VALUE) (
+ IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+ IN CHAR8 *Schema,
+ IN CHAR8 *Version,
+ IN EFI_STRING ConfigureLang,
+ IN EDKII_REDFISH_VALUE Value
+ );
+
+/**
+ Get the list of Configure Language from platform configuration by the given Schema and RegexPattern.
+
+ @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+ @param[in] Schema The Redfish schema to query.
+ @param[in] Version The Redfish version to query.
+ @param[in] RegexPattern The target Configure Language pattern. This is used for regular expression matching.
+ @param[out] ConfigureLangList The list of Configure Language.
+ @param[out] Count The number of Configure Language in ConfigureLangList.
+
+ @retval EFI_SUCCESS ConfigureLangList is returned successfully.
+ @retval Others Some error happened.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_CONFIG_LANG) (
+ IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+ IN CHAR8 *Schema,
+ IN CHAR8 *Version,
+ IN EFI_STRING RegexPattern,
+ OUT EFI_STRING **ConfigureLangList,
+ OUT UINTN *Count
+ );
+
+
+/**
+ Get the list of supported Redfish schema from platform configuration on the give HII handle.
+
+ @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+ @param[in] HiiHandle The target handle to search. If handle is NULL,
+ this function returns all schema from HII database.
+ @param[out] SupportedSchema The supported schema list which is separated by ';'.
+ For example: "x-uefi-redfish-Memory.v1_7_1;x-uefi-redfish-Boot.v1_0_1"
+ The SupportedSchema is allocated by the callee. It's caller's
+ responsibility to free this buffer using FreePool().
+
+ @retval EFI_SUCCESS Schema is returned successfully.
+ @retval Others Some error happened.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_SUPPORTED_SCHEMA) (
+ IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+ IN EFI_HII_HANDLE HiiHandle, OPTIONAL
+ OUT CHAR8 **SupportedSchema
+ );
+
+struct _EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL {
+ EDKII_REDFISH_PLATFORM_CONFIG_GET_VALUE GetValue;
+ EDKII_REDFISH_PLATFORM_CONFIG_SET_VALUE SetValue;
+ EDKII_REDFISH_PLATFORM_CONFIG_GET_CONFIG_LANG GetConfigureLang;
+ EDKII_REDFISH_PLATFORM_CONFIG_GET_SUPPORTED_SCHEMA GetSupportedSchema;
+};
+
+extern EFI_GUID gEdkIIRedfishPlatformConfigProtocolGuid;
+
+#endif
diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
index 67818cccd2..971035f27d 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
@@ -1,1304 +1,1783 @@
-/** @file
-
- The implementation of EDKII Redfidh Platform Config Protocol.
-
- (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "RedfishPlatformConfigDxe.h"
-#include "RedfishPlatformConfigImpl.h"
-
-REDFISH_PLATFORM_CONFIG_PRIVATE *mRedfishPlatformConfigPrivate = NULL;
-
-/**
- Compare two value in HII statement format.
-
- @param[in] Value1 Firt value to compare.
- @param[in] Value2 Second value to be compared.
-
- @retval UINTN 0 is retuned when two values are equal.
- 1 is returned when first value is greater than second value.
- -1 is returned when second value is greater than first value.
-
-**/
-UINTN
-CompareHiiStatementValue (
- IN HII_STATEMENT_VALUE *Value1,
- IN HII_STATEMENT_VALUE *Value2
- )
-{
- INTN Result;
- UINT64 Data1;
- UINT64 Data2;
-
- if (Value1 == NULL || Value2 == NULL) {
- return 0xFF;
- }
-
- switch (Value1->Type) {
- case EFI_IFR_TYPE_NUM_SIZE_8:
- Data1 = Value1->Value.u8;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_16:
- Data1 = Value1->Value.u16;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_32:
- Data1 = Value1->Value.u32;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_64:
- Data1 = Value1->Value.u64;
- break;
- case EFI_IFR_TYPE_BOOLEAN:
- Data1 = (Value1->Value.b ? 1 : 0);
- break;
- default:
- return 0xFF;
- }
-
- switch (Value2->Type) {
- case EFI_IFR_TYPE_NUM_SIZE_8:
- Data2 = Value2->Value.u8;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_16:
- Data2 = Value2->Value.u16;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_32:
- Data2 = Value2->Value.u32;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_64:
- Data2 = Value2->Value.u64;
- break;
- case EFI_IFR_TYPE_BOOLEAN:
- Data2 = (Value2->Value.b ? 1 : 0);
- break;
- default:
- return 0xFF;
- }
-
- Result = (Data1 == Data2 ? 0 : (Data1 > Data2 ? 1 : -1));
-
- return Result;
-}
-
-/**
- Convert HII value to the string in HII one-of opcode.
-
- @param[in] Statement Statement private instance
-
- @retval EFI_STRING_ID The string ID in HII database.
- 0 is returned when something goes wrong.
-
-**/
-EFI_STRING_ID
-HiiValueToOneOfOptionStringId (
- IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement
- )
-{
- LIST_ENTRY *Link;
- HII_QUESTION_OPTION *Option;
-
- if (Statement->HiiStatement->Operand != EFI_IFR_ONE_OF_OP) {
- return 0;
- }
-
- if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
- return 0;
- }
-
- Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
- while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
- Option = HII_QUESTION_OPTION_FROM_LINK (Link);
-
- if (CompareHiiStatementValue (&Statement->HiiStatement->Value, &Option->Value) == 0) {
- return Option->Text;
- }
-
- Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
- }
-
- return 0;
-}
-
-/**
- Convert HII string to the value in HII one-of opcode.
-
- @param[in] Statement Statement private instance
- @param[in] Schema Schema string
- @param[in] HiiString Input string
- @param[out] Value Value returned
-
- @retval EFI_SUCCESS HII value is returned successfully.
- @retval Others Errors occur
-
-**/
-EFI_STATUS
-HiiStringToOneOfOptionValue (
- IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement,
- IN CHAR8 *Schema,
- IN EFI_STRING HiiString,
- OUT HII_STATEMENT_VALUE *Value
- )
-{
- LIST_ENTRY *Link;
- HII_QUESTION_OPTION *Option;
- EFI_STRING TmpString;
- BOOLEAN Found;
-
- if (Statement == NULL || IS_EMPTY_STRING (HiiString) || Value == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (Statement->HiiStatement->Operand != EFI_IFR_ONE_OF_OP) {
- return EFI_UNSUPPORTED;
- }
-
- if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
- return EFI_NOT_FOUND;
- }
-
- Found = FALSE;
- Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
- while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
- Option = HII_QUESTION_OPTION_FROM_LINK (Link);
-
- TmpString = HiiGetRedfishString (Statement->ParentForm->ParentFormset->HiiHandle, Schema, Option->Text);
- if (TmpString != NULL) {
- if (StrCmp (TmpString, HiiString) == 0) {
- CopyMem (Value, &Option->Value, sizeof (HII_STATEMENT_VALUE));
- Found = TRUE;
- }
- FreePool (TmpString);
- }
-
- if (Found) {
- return EFI_SUCCESS;
- }
-
- Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
- }
-
- return EFI_NOT_FOUND;
-}
-
-/**
- Convert HII value to numeric value in Redfish format.
-
- @param[in] Value Value to be converted.
- @param[out] RedfishValue Value in Redfish format.
-
- @retval EFI_SUCCESS Redfish value is returned successfully.
- @retval Others Errors occur
-
-**/
-EFI_STATUS
-HiiValueToRedfishNumeric (
- IN HII_STATEMENT_VALUE *Value,
- OUT EDKII_REDFISH_VALUE *RedfishValue
- )
-{
- if (Value == NULL || RedfishValue == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- switch (Value->Type) {
- case EFI_IFR_TYPE_NUM_SIZE_8:
- RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
- RedfishValue->Value.Integer = (INT64)Value->Value.u8;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_16:
- RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
- RedfishValue->Value.Integer = (INT64)Value->Value.u16;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_32:
- RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
- RedfishValue->Value.Integer = (INT64)Value->Value.u32;
- break;
- case EFI_IFR_TYPE_NUM_SIZE_64:
- RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
- RedfishValue->Value.Integer = (INT64)Value->Value.u64;
- break;
- case EFI_IFR_TYPE_BOOLEAN:
- RedfishValue->Type = REDFISH_VALUE_TYPE_BOOLEAN;
- RedfishValue->Value.Boolean = Value->Value.b;
- break;
- default:
- RedfishValue->Type = REDFISH_VALUE_TYPE_UNKNOWN;
- break;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Convert numeric value in Redfish format to HII value.
-
- @param[in] RedfishValue Value in Redfish format to be converted.
- @param[out] Value HII value returned.
-
- @retval EFI_SUCCESS HII value is returned successfully.
- @retval Others Errors occur
-
-**/
-EFI_STATUS
-RedfishNumericToHiiValue (
- IN EDKII_REDFISH_VALUE *RedfishValue,
- OUT HII_STATEMENT_VALUE *Value
- )
-{
- if (Value == NULL || RedfishValue == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- switch (RedfishValue->Type) {
- case REDFISH_VALUE_TYPE_INTEGER:
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
- Value->Value.u64 = (UINT64)RedfishValue->Value.Integer;
- break;
- case REDFISH_VALUE_TYPE_BOOLEAN:
- Value->Type = EFI_IFR_TYPE_BOOLEAN;
- Value->Value.b = RedfishValue->Value.Boolean;
- break;
- default:
- Value->Type = EFI_IFR_TYPE_UNDEFINED;
- break;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Return the full Redfish schema string from the given Schema and Version.
-
- Returned schema string is: Schema + '.' + Version
-
- @param[in] Schema Schema string
- @param[in] Version Schema version string
-
- @retval CHAR8 * Schema string. NULL when errors occur.
-
-**/
-CHAR8 *
-GetFullSchemaString (
- IN CHAR8 *Schema,
- IN CHAR8 *Version
- )
-{
- UINTN Size;
- CHAR8 *FullName;
-
- if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version)) {
- return NULL;
- }
-
- Size = AsciiStrSize(CONFIGURE_LANGUAGE_PREFIX) + AsciiStrSize (Schema) + AsciiStrSize (Version);
-
- FullName = AllocatePool (Size);
- if (FullName == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, out-of-resource\n", __FUNCTION__));
- return NULL;
- }
-
- AsciiSPrint (FullName, Size, "%a%a.%a", CONFIGURE_LANGUAGE_PREFIX, Schema, Version);
-
- return FullName;
-}
-
-/**
- Common implementation to get statement private instance.
-
- @param[in] RedfishPlatformConfigPrivate Private instance.
- @param[in] Schema Redfish schema string.
- @param[in] ConfigureLang Configure language that refers to this statement.
- @param[out] Statement Statement instance
-
- @retval EFI_SUCCESS HII value is returned successfully.
- @retval Others Errors occur
-
-**/
-EFI_STATUS
-RedfishPlatformConfigGetStatementCommon (
- IN REDFISH_PLATFORM_CONFIG_PRIVATE *RedfishPlatformConfigPrivate,
- IN CHAR8 *Schema,
- IN EFI_STRING ConfigureLang,
- OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE **Statement
- )
-{
- EFI_STATUS Status;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
-
- if (RedfishPlatformConfigPrivate == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (ConfigureLang) || Statement == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- *Statement = NULL;
-
- Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList, &RedfishPlatformConfigPrivate->PendingList);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTION__, Status));
- return Status;
- }
-
- TargetStatement = GetStatementPrivateByConfigureLang (&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
- if (TargetStatement == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, No match HII statement is found by the given %s in schema %a\n", __FUNCTION__, ConfigureLang, Schema));
- return EFI_NOT_FOUND;
- }
-
- //
- // Find current HII question value.
- //
- Status = GetQuestionValue (
- TargetStatement->ParentForm->ParentFormset->HiiFormSet,
- TargetStatement->ParentForm->HiiForm,
- TargetStatement->HiiStatement,
- GetSetValueWithHiiDriver
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to get question current value: %r\n", __FUNCTION__, Status));
- return Status;
- }
-
-
- if (TargetStatement->HiiStatement->Value.Type == EFI_IFR_TYPE_UNDEFINED) {
- return EFI_DEVICE_ERROR;
- }
-
- //
- // Return Value.
- //
- *Statement = TargetStatement;
-
- return EFI_SUCCESS;
-}
-
-/**
- Get Redfish value with the given Schema and Configure Language.
-
- @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
- @param[in] Schema The Redfish schema to query.
- @param[in] Version The Redfish version to query.
- @param[in] ConfigureLang The target value which match this configure Language.
- @param[out] Value The returned value.
-
- @retval EFI_SUCCESS Value is returned successfully.
- @retval Others Some error happened.
-
-**/
-EFI_STATUS
-EFIAPI
-RedfishPlatformConfigProtocolGetValue (
- IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
- IN CHAR8 *Schema,
- IN CHAR8 *Version,
- IN EFI_STRING ConfigureLang,
- OUT EDKII_REDFISH_VALUE *Value
- )
-{
- EFI_STATUS Status;
- REDFISH_PLATFORM_CONFIG_PRIVATE *RedfishPlatformConfigPrivate;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
- EFI_STRING_ID StringId;
- CHAR8 *FullSchema;
- EFI_STRING HiiString;
- UINTN Size;
-
- if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || IS_EMPTY_STRING (ConfigureLang) || Value == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
- Value->Type = REDFISH_VALUE_TYPE_UNKNOWN;
- FullSchema = NULL;
- HiiString = NULL;
-
- FullSchema = GetFullSchemaString (Schema, Version);
- if (FullSchema == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Status = RedfishPlatformConfigGetStatementCommon (RedfishPlatformConfigPrivate, FullSchema, ConfigureLang, &TargetStatement);
- if (EFI_ERROR (Status)) {
- goto RELEASE_RESOURCE;
- }
-
- switch (TargetStatement->HiiStatement->Operand) {
- case EFI_IFR_ONE_OF_OP:
- StringId = HiiValueToOneOfOptionStringId (TargetStatement);
- if (StringId == 0) {
- ASSERT (FALSE);
- Status = EFI_DEVICE_ERROR;
- goto RELEASE_RESOURCE;
- }
-
- HiiString = HiiGetRedfishString (TargetStatement->ParentForm->ParentFormset->HiiHandle, FullSchema, StringId);
- if (HiiString == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, Can not find string ID: 0x%x with %a\n", __FUNCTION__, StringId, FullSchema));
- Status = EFI_NOT_FOUND;
- goto RELEASE_RESOURCE;
- }
-
- Size = StrLen (HiiString) + 1;
- Value->Value.Buffer = AllocatePool (Size);
- if (Value->Value.Buffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto RELEASE_RESOURCE;
- }
-
- UnicodeStrToAsciiStrS (HiiString, Value->Value.Buffer, Size);
- Value->Type = REDFISH_VALUE_TYPE_STRING;
-
- break;
- case EFI_IFR_STRING_OP:
- if (TargetStatement->HiiStatement->Value.Type != EFI_IFR_TYPE_STRING) {
- ASSERT (FALSE);
- Status = EFI_DEVICE_ERROR;
- goto RELEASE_RESOURCE;
- }
-
- Value->Type = REDFISH_VALUE_TYPE_STRING;
- Value->Value.Buffer = AllocateCopyPool (StrSize ((CHAR16 *)TargetStatement->HiiStatement->Value.Buffer), TargetStatement->HiiStatement->Value.Buffer);
- if (Value->Value.Buffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto RELEASE_RESOURCE;
- }
- break;
- case EFI_IFR_CHECKBOX_OP:
- case EFI_IFR_NUMERIC_OP:
- Status = HiiValueToRedfishNumeric (&TargetStatement->HiiStatement->Value, Value);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to convert HII value to Redfish value: %r\n", __FUNCTION__, Status));
- goto RELEASE_RESOURCE;
- }
- break;
- default:
- DEBUG ((DEBUG_ERROR, "%a, catch unsupported type: 0x%x! Please contact with author if we need to support this type.\n", __FUNCTION__, TargetStatement->HiiStatement->Operand));
- ASSERT (FALSE);
- Status = EFI_UNSUPPORTED;
- goto RELEASE_RESOURCE;
- }
-
-RELEASE_RESOURCE:
-
- if (FullSchema != NULL) {
- FreePool (FullSchema);
- }
-
- if (HiiString != NULL) {
- FreePool (HiiString);
- }
-
- return Status;
-}
-
-/**
- Function to save question value into HII database.
-
- @param[in] HiiFormset HII form-set instance
- @param[in] HiiForm HII form instance
- @param[in] HiiStatement HII statement that keeps new value.
- @param[in] Value New value to applyu.
-
- @retval EFI_SUCCESS HII value is returned successfully.
- @retval Others Errors occur
-
-**/
-EFI_STATUS
-RedfishPlatformConfigSaveQuestionValue (
- IN HII_FORMSET *HiiFormset,
- IN HII_FORM *HiiForm,
- IN HII_STATEMENT *HiiStatement,
- IN HII_STATEMENT_VALUE *Value
- )
-{
- EFI_STATUS Status;
-
- if (HiiFormset == NULL || HiiForm == NULL || HiiStatement == NULL || Value == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- Status = SetQuestionValue (
- HiiFormset,
- HiiForm,
- HiiStatement,
- Value
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to set question value: %r\n", __FUNCTION__, Status));
- return Status;
- }
-
- Status = SubmitForm (HiiFormset, HiiForm);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to submit form: %r\n", __FUNCTION__, Status));
- return Status;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Common implementation to set statement private instance.
-
- @param[in] RedfishPlatformConfigPrivate Private instance.
- @param[in] Schema Redfish schema string.
- @param[in] ConfigureLang Configure language that refers to this statement.
- @param[in] Statement Statement instance
-
- @retval EFI_SUCCESS HII value is returned successfully.
- @retval Others Errors occur
-
-**/
-EFI_STATUS
-RedfishPlatformConfigSetStatementCommon (
- IN REDFISH_PLATFORM_CONFIG_PRIVATE *RedfishPlatformConfigPrivate,
- IN CHAR8 *Schema,
- IN EFI_STRING ConfigureLang,
- IN HII_STATEMENT_VALUE *StatementValue
- )
-{
- EFI_STATUS Status;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
- EFI_STRING TempBuffer;
-
- if (RedfishPlatformConfigPrivate == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (ConfigureLang) || StatementValue == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- TempBuffer = NULL;
-
- Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList, &RedfishPlatformConfigPrivate->PendingList);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTION__, Status));
- return Status;
- }
-
- TargetStatement = GetStatementPrivateByConfigureLang (&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
- if (TargetStatement == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, No match HII statement is found by the given %s in schema %a\n", __FUNCTION__, ConfigureLang, Schema));
- return EFI_NOT_FOUND;
- }
-
- if (StatementValue->Type != TargetStatement->HiiStatement->Value.Type) {
- //
- // We treat one-of type as string in Redfish. But one-of statement is not
- // in string format from HII point of view. Do a patch here.
- //
- if (TargetStatement->HiiStatement->Operand == EFI_IFR_ONE_OF_OP && StatementValue->Type == EFI_IFR_TYPE_STRING) {
- TempBuffer = AllocatePool (StatementValue->BufferLen * sizeof (CHAR16));
- if (TempBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- AsciiStrToUnicodeStrS (StatementValue->Buffer, TempBuffer, StatementValue->BufferLen);
- FreePool (StatementValue->Buffer);
- StatementValue->Buffer = NULL;
- StatementValue->BufferLen = 0;
-
- Status = HiiStringToOneOfOptionValue (TargetStatement, Schema, TempBuffer, StatementValue);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to find option value by the given %s\n", __FUNCTION__, TempBuffer));
- FreePool (TempBuffer);
- return EFI_NOT_FOUND;
- }
-
- FreePool (TempBuffer);
- } else if (TargetStatement->HiiStatement->Operand == EFI_IFR_NUMERIC_OP && StatementValue->Type == EFI_IFR_TYPE_NUM_SIZE_64) {
- //
- // Redfish only has numeric value type and it does not care about the value size.
- // Do a patch here so we have proper value size applied.
- //
- StatementValue->Type = TargetStatement->HiiStatement->Value.Type;
- } else {
- DEBUG ((DEBUG_ERROR, "%a, catch value type mismatch! input type: 0x%x but target value type: 0x%x\n", __FUNCTION__, StatementValue->Type, TargetStatement->HiiStatement->Value.Type));
- ASSERT (FALSE);
- }
- }
-
- Status = RedfishPlatformConfigSaveQuestionValue (
- TargetStatement->ParentForm->ParentFormset->HiiFormSet,
- TargetStatement->ParentForm->HiiForm,
- TargetStatement->HiiStatement,
- StatementValue
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to save question value: %r\n", __FUNCTION__, Status));
- return Status;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Set Redfish value with the given Schema and Configure Language.
-
- @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
- @param[in] Schema The Redfish schema to query.
- @param[in] Version The Redfish version to query.
- @param[in] ConfigureLang The target value which match this configure Language.
- @param[in] Value The value to set.
-
- @retval EFI_SUCCESS Value is returned successfully.
- @retval Others Some error happened.
-
-**/
-EFI_STATUS
-EFIAPI
-RedfishPlatformConfigProtocolSetValue (
- IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
- IN CHAR8 *Schema,
- IN CHAR8 *Version,
- IN EFI_STRING ConfigureLang,
- IN EDKII_REDFISH_VALUE Value
- )
-{
- EFI_STATUS Status;
- REDFISH_PLATFORM_CONFIG_PRIVATE *RedfishPlatformConfigPrivate;
- CHAR8 *FullSchema;
- HII_STATEMENT_VALUE NewValue;
-
- if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || IS_EMPTY_STRING (ConfigureLang)) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (Value.Type == REDFISH_VALUE_TYPE_UNKNOWN || Value.Type >= REDFISH_VALUE_TYPE_MAX) {
- return EFI_INVALID_PARAMETER;
- }
-
- RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
- FullSchema = NULL;
-
- FullSchema = GetFullSchemaString (Schema, Version);
- if (FullSchema == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- ZeroMem (&NewValue, sizeof (HII_STATEMENT_VALUE));
-
- switch (Value.Type) {
- case REDFISH_VALUE_TYPE_INTEGER:
- case REDFISH_VALUE_TYPE_BOOLEAN:
- Status = RedfishNumericToHiiValue (&Value, &NewValue);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to convert Redfish value to Hii value: %r\n", __FUNCTION__, Status));
- goto RELEASE_RESOURCE;
- }
- break;
- case REDFISH_VALUE_TYPE_STRING:
- NewValue.Type = EFI_IFR_TYPE_STRING;
- NewValue.BufferLen = (UINT16)AsciiStrSize (Value.Value.Buffer);
- NewValue.Buffer = AllocateCopyPool (NewValue.BufferLen, Value.Value.Buffer);
- if (NewValue.Buffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto RELEASE_RESOURCE;
- }
- break;
- default:
- ASSERT (FALSE);
- break;
- }
-
- Status = RedfishPlatformConfigSetStatementCommon (RedfishPlatformConfigPrivate, FullSchema, ConfigureLang, &NewValue);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to set value to statement: %r\n", __FUNCTION__, Status));
- }
-
-RELEASE_RESOURCE:
-
- if (FullSchema != NULL) {
- FreePool (FullSchema);
- }
-
- return Status;
-}
-
-/**
- Get the list of Configure Language from platform configuration by the given Schema and Pattern.
-
- @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
- @param[in] Schema The Redfish schema to query.
- @param[in] Version The Redfish version to query.
- @param[in] Pattern The target Configure Language pattern.
- @param[out] ConfigureLangList The list of Configure Language.
- @param[out] Count The number of Configure Language in ConfigureLangList.
-
- @retval EFI_SUCCESS ConfigureLangList is returned successfully.
- @retval Others Some error happened.
-
-**/
-EFI_STATUS
-EFIAPI
-RedfishPlatformConfigProtocolGetConfigureLang (
- IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
- IN CHAR8 *Schema,
- IN CHAR8 *Version,
- IN EFI_STRING Pattern,
- OUT EFI_STRING **ConfigureLangList,
- OUT UINTN *Count
- )
-{
- REDFISH_PLATFORM_CONFIG_PRIVATE *RedfishPlatformConfigPrivate;
- EFI_STATUS Status;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST StatementList;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF *StatementRef;
- LIST_ENTRY *NextLink;
- EFI_STRING TmpString;
- EFI_STRING *TmpConfigureLangList;
- UINTN Index;
- CHAR8 *FullSchema;
-
- if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || Count == NULL || ConfigureLangList == NULL || IS_EMPTY_STRING (Pattern)) {
- return EFI_INVALID_PARAMETER;
- }
-
- *Count = 0;
- *ConfigureLangList = NULL;
- FullSchema = NULL;
- RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
-
- Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList, &RedfishPlatformConfigPrivate->PendingList);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTION__, Status));
- return Status;
- }
-
- FullSchema = GetFullSchemaString (Schema, Version);
- if (FullSchema == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Status = GetStatementPrivateByConfigureLangRegex (
- RedfishPlatformConfigPrivate->RegularExpressionProtocol,
- &RedfishPlatformConfigPrivate->FormsetList,
- FullSchema,
- Pattern,
- &StatementList
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, GetStatementPrivateByConfigureLangRegex failure: %r\n", __FUNCTION__, Status));
- goto RELEASE_RESOURCE;
- }
-
- if (!IsListEmpty (&StatementList.StatementList)) {
-
- TmpConfigureLangList = AllocateZeroPool (sizeof (CHAR16 *) * StatementList.Count);
- if (TmpConfigureLangList == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto RELEASE_RESOURCE;
- }
-
- Index = 0;
- NextLink = GetFirstNode (&StatementList.StatementList);
- while (!IsNull (&StatementList.StatementList, NextLink)) {
- StatementRef = REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
- NextLink = GetNextNode (&StatementList.StatementList, NextLink);
-
- ASSERT (StatementRef->Statement->Description != 0);
- if (StatementRef->Statement->Description != 0) {
- TmpString = HiiGetRedfishString (StatementRef->Statement->ParentForm->ParentFormset->HiiHandle, FullSchema, StatementRef->Statement->Description);
- ASSERT (TmpString != NULL);
- if (TmpString != NULL) {
- TmpConfigureLangList[Index] = AllocateCopyPool (StrSize (TmpString), TmpString);
- ASSERT (TmpConfigureLangList[Index] != NULL);
- FreePool (TmpString);
- ++Index;
- }
- }
- }
- }
-
- *Count = StatementList.Count;
- *ConfigureLangList = TmpConfigureLangList;
-
-RELEASE_RESOURCE:
-
- if (FullSchema != NULL) {
- FreePool (FullSchema);
- }
-
- ReleaseStatementList (&StatementList);
-
- return Status;
-}
-
-
-/**
- Get the list of supported Redfish schema from paltform configuration on give HII handle.
-
- @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
- @param[in] HiiHandle The target handle to search. If handle is NULL,
- this function return all schema from HII database.
- @param[out] SupportedSchema The supported schema list which is separated by ';'.
- The SupportedSchema is allocated by the callee. It's caller's
- responsibility to free this buffer using FreePool().
-
- @retval EFI_SUCCESS Schema is returned successfully.
- @retval Others Some error happened.
-
-**/
-EFI_STATUS
-EFIAPI
-RedfishPlatformConfigProtocolGetSupportedSchema (
- IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
- IN EFI_HII_HANDLE HiiHandle, OPTIONAL
- OUT CHAR8 **SupportedSchema
- )
-{
- REDFISH_PLATFORM_CONFIG_PRIVATE *RedfishPlatformConfigPrivate;
- EFI_STATUS Status;
- LIST_ENTRY *HiiFormsetLink;
- LIST_ENTRY *HiiFormsetNextLink;
- REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
- UINTN Index;
- UINTN StringSize;
- CHAR8 *StringBuffer;
- UINTN StringIndex;
-
- if (This == NULL || SupportedSchema == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- *SupportedSchema = NULL;
-
- RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
-
- Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList, &RedfishPlatformConfigPrivate->PendingList);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTION__, Status));
- return Status;
- }
-
- if (IsListEmpty (&RedfishPlatformConfigPrivate->FormsetList)) {
- return EFI_NOT_FOUND;
- }
-
- //
- // Calculate for string buffer size.
- //
- StringSize = 0;
- HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate->FormsetList);
- while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLink)) {
- HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLink);
- HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
- if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
- HiiFormsetLink = HiiFormsetNextLink;
- continue;
- }
-
- if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
- for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count; Index++) {
- StringSize += AsciiStrSize (HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
- }
- }
-
- HiiFormsetLink = HiiFormsetNextLink;
- }
-
- if (StringSize == 0) {
- return EFI_NOT_FOUND;
- }
-
- StringBuffer = AllocatePool (StringSize);
- if (StringBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- StringIndex = 0;
- HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate->FormsetList);
- while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLink)) {
- HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLink);
- HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
- if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
- HiiFormsetLink = HiiFormsetNextLink;
- continue;
- }
-
- if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
- for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count; Index++) {
- AsciiStrCpyS (&StringBuffer[StringIndex], (StringSize - StringIndex), HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
- StringIndex += AsciiStrLen (HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
- StringBuffer[StringIndex] = ';';
- ++StringIndex;
- }
- }
-
- HiiFormsetLink = HiiFormsetNextLink;
- }
-
- StringBuffer[--StringIndex] = '\0';
-
- *SupportedSchema = StringBuffer;
-
- return EFI_SUCCESS;
-}
-
-/**
- Functions which are registered to receive notification of
- database events have this prototype. The actual event is encoded
- in NotifyType. The following table describes how PackageType,
- PackageGuid, Handle, and Package are used for each of the
- notification types.
-
- @param[in] PackageType Package type of the notification.
- @param[in] PackageGuid If PackageType is
- EFI_HII_PACKAGE_TYPE_GUID, then this is
- the pointer to the GUID from the Guid
- field of EFI_HII_PACKAGE_GUID_HEADER.
- Otherwise, it must be NULL.
- @param[in] Package Points to the package referred to by the
- notification Handle The handle of the package
- list which contains the specified package.
- @param[in] Handle The HII handle.
- @param[in] NotifyType The type of change concerning the
- database. See
- EFI_HII_DATABASE_NOTIFY_TYPE.
-
-**/
-EFI_STATUS
-EFIAPI
-RedfishPlatformConfigFormUpdateNotify (
- IN UINT8 PackageType,
- IN CONST EFI_GUID *PackageGuid,
- IN CONST EFI_HII_PACKAGE_HEADER *Package,
- IN EFI_HII_HANDLE Handle,
- IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
- )
-{
- EFI_STATUS Status;
-
- if (NotifyType == EFI_HII_DATABASE_NOTIFY_NEW_PACK || NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
- //
- // HII formset on this handle is updated by driver during run-time. The formset needs to be reloaded.
- //
- Status = NotifyFormsetUpdate (Handle, &mRedfishPlatformConfigPrivate->PendingList);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to notify updated formset of HII handle: 0x%x\n", __FUNCTION__, Handle));
- return Status;
- }
- } else if (NotifyType == EFI_HII_DATABASE_NOTIFY_REMOVE_PACK) {
- //
- // HII resource is removed. The formset is no longer exist.
- //
- Status = NotifyFormsetDeleted (Handle, &mRedfishPlatformConfigPrivate->PendingList);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, failed to notify deleted formset of HII handle: 0x%x\n", __FUNCTION__, Handle));
- return Status;
- }
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- This is a EFI_HII_STRING_PROTOCOL notification event handler.
-
- Install HII package notification.
-
- @param[in] Event Event whose notification function is being invoked.
- @param[in] Context Pointer to the notification function's context.
-
-**/
-VOID
-EFIAPI
-HiiStringProtocolInstalled (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-{
- EFI_STATUS Status;
-
- //
- // Locate HII database protocol.
- //
- Status = gBS->LocateProtocol (
- &gEfiHiiStringProtocolGuid,
- NULL,
- (VOID **)&mRedfishPlatformConfigPrivate->HiiString
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, locate EFI_HII_STRING_PROTOCOL failure: %r\n", __FUNCTION__, Status));
- return;
- }
-
- gBS->CloseEvent (Event);
- mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent = NULL;
-}
-
-/**
- This is a EFI_HII_DATABASE_PROTOCOL notification event handler.
-
- Install HII package notification.
-
- @param[in] Event Event whose notification function is being invoked.
- @param[in] Context Pointer to the notification function's context.
-
-**/
-VOID
-EFIAPI
-HiiDatabaseProtocolInstalled (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-{
- EFI_STATUS Status;
-
- //
- // Locate HII database protocol.
- //
- Status = gBS->LocateProtocol (
- &gEfiHiiDatabaseProtocolGuid,
- NULL,
- (VOID **)&mRedfishPlatformConfigPrivate->HiiDatabase
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, locate EFI_HII_DATABASE_PROTOCOL failure: %r\n", __FUNCTION__, Status));
- return;
- }
-
- //
- // Register package notification when new form package is installed.
- //
- Status = mRedfishPlatformConfigPrivate->HiiDatabase->RegisterPackageNotify (
- mRedfishPlatformConfigPrivate->HiiDatabase,
- EFI_HII_PACKAGE_FORMS,
- NULL,
- RedfishPlatformConfigFormUpdateNotify,
- EFI_HII_DATABASE_NOTIFY_NEW_PACK,
- &mRedfishPlatformConfigPrivate->NotifyHandle
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__, Status));
- }
-
- //
- // Register package notification when new form package is updated.
- //
- Status = mRedfishPlatformConfigPrivate->HiiDatabase->RegisterPackageNotify (
- mRedfishPlatformConfigPrivate->HiiDatabase,
- EFI_HII_PACKAGE_FORMS,
- NULL,
- RedfishPlatformConfigFormUpdateNotify,
- EFI_HII_DATABASE_NOTIFY_ADD_PACK,
- &mRedfishPlatformConfigPrivate->NotifyHandle
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__, Status));
- }
-
-#if REDFISH_PLATFORM_CONFIG_DELETE_EXPIRED_FORMSET
- //
- // Register package notification when new form package is removed.
- //
- Status = mRedfishPlatformConfigPrivate->HiiDatabase->RegisterPackageNotify (
- mRedfishPlatformConfigPrivate->HiiDatabase,
- EFI_HII_PACKAGE_FORMS,
- NULL,
- RedfishPlatformConfigFormUpdateNotify,
- EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
- &mRedfishPlatformConfigPrivate->NotifyHandle
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__, Status));
- }
-#endif
-
- gBS->CloseEvent (Event);
- mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent = NULL;
-
-}
-
-/**
- This is a EFI_REGULAR_EXPRESSION_PROTOCOL notification event handler.
-
- @param[in] Event Event whose notification function is being invoked.
- @param[in] Context Pointer to the notification function's context.
-
-**/
-VOID
-EFIAPI
-RegexProtocolInstalled (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-{
- EFI_STATUS Status;
-
- //
- // Locate regular expression protocol.
- //
- Status = gBS->LocateProtocol (
- &gEfiRegularExpressionProtocolGuid,
- NULL,
- (VOID **)&mRedfishPlatformConfigPrivate->RegularExpressionProtocol
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, locate EFI_REGULAR_EXPRESSION_PROTOCOL failure: %r\n", __FUNCTION__, Status));
- return;
- }
-
- gBS->CloseEvent (Event);
- mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent = NULL;
-
-}
-
-/**
- Unloads an image.
-
- @param ImageHandle Handle that identifies the image to be unloaded.
-
- @retval EFI_SUCCESS The image has been unloaded.
- @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
-
-**/
-EFI_STATUS
-EFIAPI
-RedfishPlatformConfigDxeUnload (
- IN EFI_HANDLE ImageHandle
- )
-{
- EFI_STATUS Status;
-
- if (mRedfishPlatformConfigPrivate != NULL) {
- Status = gBS->UninstallProtocolInterface (
- mRedfishPlatformConfigPrivate->ImageHandle,
- &gEdkIIRedfishPlatformConfigProtocolGuid,
- (VOID*)&mRedfishPlatformConfigPrivate->Protocol
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, can not uninstall gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
- ASSERT (FALSE);
- }
-
- //
- // Close events
- //
- if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent != NULL) {
- gBS->CloseEvent (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent);
- }
- if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent != NULL) {
- gBS->CloseEvent (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent);
- }
- if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent != NULL) {
- gBS->CloseEvent (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent);
- }
-
- //
- // Unregister package notification.
- //
- if (mRedfishPlatformConfigPrivate->NotifyHandle != NULL) {
- mRedfishPlatformConfigPrivate->HiiDatabase->UnregisterPackageNotify (
- mRedfishPlatformConfigPrivate->HiiDatabase,
- mRedfishPlatformConfigPrivate->NotifyHandle
- );
- }
-
- ReleaseFormsetList (&mRedfishPlatformConfigPrivate->FormsetList);
- FreePool (mRedfishPlatformConfigPrivate);
- mRedfishPlatformConfigPrivate = NULL;
- }
-
- return EFI_SUCCESS;
-}
-
-
-/**
- This is the declaration of an EFI image entry point. This entry point is
- the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
- both device drivers and bus drivers.
-
- @param ImageHandle The firmware allocated handle for the UEFI image.
- @param SystemTable A pointer to the EFI System Table.
-
- @retval EFI_SUCCESS The operation completed successfully.
- @retval Others An unexpected error occurred.
-**/
-EFI_STATUS
-EFIAPI
-RedfishPlatformConfigDxeEntryPoint (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
-
- mRedfishPlatformConfigPrivate = (REDFISH_PLATFORM_CONFIG_PRIVATE *)AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PRIVATE));
- if (mRedfishPlatformConfigPrivate == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, can not allocate pool for REDFISH_PLATFORM_CONFIG_PRIVATE\n", __FUNCTION__));
- ASSERT (FALSE);
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Protocol initialization
- //
- mRedfishPlatformConfigPrivate->ImageHandle = ImageHandle;
- mRedfishPlatformConfigPrivate->Protocol.GetValue = RedfishPlatformConfigProtocolGetValue;
- mRedfishPlatformConfigPrivate->Protocol.SetValue = RedfishPlatformConfigProtocolSetValue;
- mRedfishPlatformConfigPrivate->Protocol.GetConfigureLang = RedfishPlatformConfigProtocolGetConfigureLang;
- mRedfishPlatformConfigPrivate->Protocol.GetSupportedSchema = RedfishPlatformConfigProtocolGetSupportedSchema;
-
- InitializeListHead (&mRedfishPlatformConfigPrivate->FormsetList);
- InitializeListHead (&mRedfishPlatformConfigPrivate->PendingList);
-
- Status = gBS->InstallProtocolInterface (
- &ImageHandle,
- &gEdkIIRedfishPlatformConfigProtocolGuid,
- EFI_NATIVE_INTERFACE,
- (VOID*)&mRedfishPlatformConfigPrivate->Protocol
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a, can not install gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
- ASSERT (FALSE);
- }
-
- //
- // Install protocol notification if HII database protocol is installed.
- //
- mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent = EfiCreateProtocolNotifyEvent (
- &gEfiHiiDatabaseProtocolGuid,
- TPL_CALLBACK,
- HiiDatabaseProtocolInstalled,
- NULL,
- &mRedfishPlatformConfigPrivate->HiiDbNotify.Registration
- );
- if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for gEfiHiiDatabaseProtocolGuid\n", __FUNCTION__));
- ASSERT (FALSE);
- }
-
- //
- // Install protocol notification if HII string protocol is installed.
- //
- mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent = EfiCreateProtocolNotifyEvent (
- &gEfiHiiStringProtocolGuid,
- TPL_CALLBACK,
- HiiStringProtocolInstalled,
- NULL,
- &mRedfishPlatformConfigPrivate->HiiStringNotify.Registration
- );
- if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for gEfiHiiStringProtocolGuid\n", __FUNCTION__));
- ASSERT (FALSE);
- }
-
- //
- // Install protocol notification if regular expression protocol is installed.
- //
- mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent = EfiCreateProtocolNotifyEvent (
- &gEfiRegularExpressionProtocolGuid,
- TPL_CALLBACK,
- RegexProtocolInstalled,
- NULL,
- &mRedfishPlatformConfigPrivate->RegexNotify.Registration
- );
- if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent == NULL) {
- DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for gEfiRegularExpressionProtocolGuid\n", __FUNCTION__));
- ASSERT (FALSE);
- }
-
- return EFI_SUCCESS;
-}
+/** @file
+
+ The implementation of EDKII Redfidh Platform Config Protocol.
+
+ (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "RedfishPlatformConfigDxe.h"
+#include "RedfishPlatformConfigImpl.h"
+
+REDFISH_PLATFORM_CONFIG_PRIVATE *mRedfishPlatformConfigPrivate = NULL;
+
+
+/**
+ Zero extend integer/boolean to UINT64 for comparing.
+
+ @param Value HII Value to be converted.
+
+**/
+UINT64
+ExtendHiiValueToU64 (
+ IN HII_STATEMENT_VALUE *Value
+ )
+{
+ UINT64 Temp;
+
+ Temp = 0;
+ switch (Value->Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ Temp = Value->Value.u8;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ Temp = Value->Value.u16;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ Temp = Value->Value.u32;
+ break;
+
+ case EFI_IFR_TYPE_BOOLEAN:
+ Temp = Value->Value.b;
+ break;
+
+ case EFI_IFR_TYPE_TIME:
+ case EFI_IFR_TYPE_DATE:
+ default:
+ break;
+ }
+
+ return Temp;
+}
+
+/**
+ Set value of a data element in an Array by its Index in ordered list buffer.
+
+ @param Array The data array.
+ @param Type Type of the data in this array.
+ @param Index Zero based index for data in this array.
+ @param Value The value to be set.
+
+**/
+VOID
+OrderedListSetArrayData (
+ IN VOID *Array,
+ IN UINT8 Type,
+ IN UINTN Index,
+ IN UINT64 Value
+ )
+{
+
+ ASSERT (Array != NULL);
+
+ switch (Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ *(((UINT8 *) Array) + Index) = (UINT8) Value;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ *(((UINT16 *) Array) + Index) = (UINT16) Value;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ *(((UINT32 *) Array) + Index) = (UINT32) Value;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ *(((UINT64 *) Array) + Index) = (UINT64) Value;
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ Return data element in an Array by its Index in ordered list array buffer.
+
+ @param Array The data array.
+ @param Type Type of the data in this array.
+ @param Index Zero based index for data in this array.
+
+ @retval Value The data to be returned
+
+**/
+UINT64
+OrderedListGetArrayData (
+ IN VOID *Array,
+ IN UINT8 Type,
+ IN UINTN Index
+ )
+{
+ UINT64 Data;
+
+ ASSERT (Array != NULL);
+
+ Data = 0;
+ switch (Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ Data = (UINT64) *(((UINT8 *) Array) + Index);
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ Data = (UINT64) *(((UINT16 *) Array) + Index);
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ Data = (UINT64) *(((UINT32 *) Array) + Index);
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ Data = (UINT64) *(((UINT64 *) Array) + Index);
+ break;
+
+ default:
+ break;
+ }
+
+ return Data;
+}
+
+/**
+ Find string ID of option if its value equals to given value.
+
+ @param[in] HiiStatement Statement to search.
+ @param[in] Value Target value.
+
+ @retval EFI_SUCCESS HII value is returned successfully.
+ @retval Others Errors occur
+
+**/
+EFI_STRING_ID
+OrderedListOptionValueToStringId (
+ IN HII_STATEMENT *HiiStatement,
+ IN UINT64 Value
+ )
+{
+ LIST_ENTRY *Link;
+ HII_QUESTION_OPTION *Option;
+ BOOLEAN Found;
+ UINT64 CurrentValue;
+
+ if (HiiStatement == NULL) {
+ return 0;
+ }
+
+ if (HiiStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
+ return 0;
+ }
+
+ if (IsListEmpty (&HiiStatement->OptionListHead)) {
+ return 0;
+ }
+
+ Found = FALSE;
+ Link = GetFirstNode (&HiiStatement->OptionListHead);
+ while (!IsNull (&HiiStatement->OptionListHead, Link)) {
+ Option = HII_QUESTION_OPTION_FROM_LINK (Link);
+
+ CurrentValue = ExtendHiiValueToU64 (&Option->Value);
+ if (Value == CurrentValue) {
+ return Option->Text;
+ }
+
+ Link = GetNextNode (&HiiStatement->OptionListHead, Link);
+ }
+
+ return 0;
+}
+
+/**
+ Compare two value in HII statement format.
+
+ @param[in] Value1 Firt value to compare.
+ @param[in] Value2 Second value to be compared.
+
+ @retval INTN 0 is retuned when two values are equal.
+ 1 is returned when first value is greater than second value.
+ -1 is returned when second value is greater than first value.
+
+**/
+INTN
+CompareHiiStatementValue (
+ IN HII_STATEMENT_VALUE *Value1,
+ IN HII_STATEMENT_VALUE *Value2
+ )
+{
+ INTN Result;
+ UINT64 Data1;
+ UINT64 Data2;
+
+ if (Value1 == NULL || Value2 == NULL) {
+ return -1;
+ }
+
+ switch (Value1->Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ Data1 = Value1->Value.u8;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ Data1 = Value1->Value.u16;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ Data1 = Value1->Value.u32;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ Data1 = Value1->Value.u64;
+ break;
+ case EFI_IFR_TYPE_BOOLEAN:
+ Data1 = (Value1->Value.b ? 1 : 0);
+ break;
+ default:
+ return -1;
+ }
+
+ switch (Value2->Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ Data2 = Value2->Value.u8;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ Data2 = Value2->Value.u16;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ Data2 = Value2->Value.u32;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ Data2 = Value2->Value.u64;
+ break;
+ case EFI_IFR_TYPE_BOOLEAN:
+ Data2 = (Value2->Value.b ? 1 : 0);
+ break;
+ default:
+ return -1;
+ }
+
+ Result = (Data1 == Data2 ? 0 : (Data1 > Data2 ? 1 : -1));
+
+ return Result;
+}
+
+/**
+ Convert HII value to the string in HII one-of opcode.
+
+ @param[in] Statement Statement private instance
+
+ @retval EFI_STRING_ID The string ID in HII database.
+ 0 is returned when something goes wrong.
+
+**/
+EFI_STRING_ID
+HiiValueToOneOfOptionStringId (
+ IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement
+ )
+{
+ LIST_ENTRY *Link;
+ HII_QUESTION_OPTION *Option;
+
+ if (Statement->HiiStatement->Operand != EFI_IFR_ONE_OF_OP) {
+ return 0;
+ }
+
+ if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
+ return 0;
+ }
+
+ Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
+ while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
+ Option = HII_QUESTION_OPTION_FROM_LINK (Link);
+
+ if (CompareHiiStatementValue (&Statement->HiiStatement->Value, &Option->Value) == 0) {
+ return Option->Text;
+ }
+
+ Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
+ }
+
+ return 0;
+}
+
+/**
+ Convert HII string to the value in HII one-of opcode.
+
+ @param[in] Statement Statement private instance
+ @param[in] Schema Schema string
+ @param[in] HiiString Input string
+ @param[out] Value Value returned
+
+ @retval EFI_SUCCESS HII value is returned successfully.
+ @retval Others Errors occur
+
+**/
+EFI_STATUS
+HiiStringToOneOfOptionValue (
+ IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement,
+ IN CHAR8 *Schema,
+ IN EFI_STRING HiiString,
+ OUT HII_STATEMENT_VALUE *Value
+ )
+{
+ LIST_ENTRY *Link;
+ HII_QUESTION_OPTION *Option;
+ EFI_STRING TmpString;
+ BOOLEAN Found;
+
+ if (Statement == NULL || IS_EMPTY_STRING (HiiString) || Value == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Statement->HiiStatement->Operand != EFI_IFR_ONE_OF_OP) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
+ return EFI_NOT_FOUND;
+ }
+
+ Found = FALSE;
+ Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
+ while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
+ Option = HII_QUESTION_OPTION_FROM_LINK (Link);
+
+ TmpString = HiiGetRedfishString (Statement->ParentForm->ParentFormset->HiiHandle, Schema, Option->Text);
+ if (TmpString != NULL) {
+ if (StrCmp (TmpString, HiiString) == 0) {
+ CopyMem (Value, &Option->Value, sizeof (HII_STATEMENT_VALUE));
+ Found = TRUE;
+ }
+ FreePool (TmpString);
+ }
+
+ if (Found) {
+ return EFI_SUCCESS;
+ }
+
+ Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Convert HII value to numeric value in Redfish format.
+
+ @param[in] Value Value to be converted.
+ @param[out] RedfishValue Value in Redfish format.
+
+ @retval EFI_SUCCESS Redfish value is returned successfully.
+ @retval Others Errors occur
+
+**/
+EFI_STATUS
+HiiValueToRedfishNumeric (
+ IN HII_STATEMENT_VALUE *Value,
+ OUT EDKII_REDFISH_VALUE *RedfishValue
+ )
+{
+ if (Value == NULL || RedfishValue == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ switch (Value->Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
+ RedfishValue->Value.Integer = (INT64)Value->Value.u8;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
+ RedfishValue->Value.Integer = (INT64)Value->Value.u16;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
+ RedfishValue->Value.Integer = (INT64)Value->Value.u32;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
+ RedfishValue->Value.Integer = (INT64)Value->Value.u64;
+ break;
+ case EFI_IFR_TYPE_BOOLEAN:
+ RedfishValue->Type = REDFISH_VALUE_TYPE_BOOLEAN;
+ RedfishValue->Value.Boolean = Value->Value.b;
+ break;
+ default:
+ RedfishValue->Type = REDFISH_VALUE_TYPE_UNKNOWN;
+ break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Convert numeric value in Redfish format to HII value.
+
+ @param[in] RedfishValue Value in Redfish format to be converted.
+ @param[out] Value HII value returned.
+
+ @retval EFI_SUCCESS HII value is returned successfully.
+ @retval Others Errors occur
+
+**/
+EFI_STATUS
+RedfishNumericToHiiValue (
+ IN EDKII_REDFISH_VALUE *RedfishValue,
+ OUT HII_STATEMENT_VALUE *Value
+ )
+{
+ if (Value == NULL || RedfishValue == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ switch (RedfishValue->Type) {
+ case REDFISH_VALUE_TYPE_INTEGER:
+ Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
+ Value->Value.u64 = (UINT64)RedfishValue->Value.Integer;
+ break;
+ case REDFISH_VALUE_TYPE_BOOLEAN:
+ Value->Type = EFI_IFR_TYPE_BOOLEAN;
+ Value->Value.b = RedfishValue->Value.Boolean;
+ break;
+ default:
+ Value->Type = EFI_IFR_TYPE_UNDEFINED;
+ break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Dump the value in ordered list buffer.
+
+ @param[in] OrderedListStatement Ordered list statement.
+
+**/
+VOID
+DumpOrderedListValue (
+ IN HII_STATEMENT *OrderedListStatement
+ )
+{
+ UINT8 *Value8;
+ UINT16 *Value16;
+ UINT32 *Value32;
+ UINT64 *Value64;
+ UINTN Count;
+ UINTN Index;
+
+ if (OrderedListStatement == NULL || OrderedListStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
+ return;
+ }
+
+ DEBUG ((DEBUG_ERROR, "Value.Type= 0x%x\n", OrderedListStatement->Value.Type));
+ DEBUG ((DEBUG_ERROR, "Value.BufferValueType= 0x%x\n", OrderedListStatement->Value.BufferValueType));
+ DEBUG ((DEBUG_ERROR, "Value.BufferLen= 0x%x\n", OrderedListStatement->Value.BufferLen));
+ DEBUG ((DEBUG_ERROR, "Value.Buffer= 0x%x\n", OrderedListStatement->Value.Buffer));
+ DEBUG ((DEBUG_ERROR, "Value.MaxContainers= 0x%x\n", OrderedListStatement->ExtraData.OrderListData.MaxContainers));
+ DEBUG ((DEBUG_ERROR, "StorageWidth= 0x%x\n", OrderedListStatement->StorageWidth));
+
+ if (OrderedListStatement->Value.Buffer == NULL) {
+ return;
+ }
+
+ Value8 = NULL;
+ Value16 = NULL;
+ Value32 = NULL;
+ Value64 = NULL;
+ Count = 0;
+
+ switch (OrderedListStatement->Value.BufferValueType) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ Value8 = (UINT8 *)OrderedListStatement->Value.Buffer;
+ Count = OrderedListStatement->StorageWidth / sizeof (UINT8);
+ for (Index = 0; Index < Count; Index++) {
+ DEBUG ((DEBUG_ERROR, "%d ", Value8[Index]));
+ }
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ Value16 = (UINT16 *)OrderedListStatement->Value.Buffer;
+ Count = OrderedListStatement->StorageWidth / sizeof (UINT16);
+ for (Index = 0; Index < Count; Index++) {
+ DEBUG ((DEBUG_ERROR, "%d ", Value16[Index]));
+ }
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ Value32 = (UINT32 *)OrderedListStatement->Value.Buffer;
+ Count = OrderedListStatement->StorageWidth / sizeof (UINT32);
+ for (Index = 0; Index < Count; Index++) {
+ DEBUG ((DEBUG_ERROR, "%d ", Value32[Index]));
+ }
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ Value64 = (UINT64 *)OrderedListStatement->Value.Buffer;
+ Count = OrderedListStatement->StorageWidth / sizeof (UINT64);
+ for (Index = 0; Index < Count; Index++) {
+ DEBUG ((DEBUG_ERROR, "%d ", Value64[Index]));
+ }
+ break;
+ default:
+ Value8 = (UINT8 *)OrderedListStatement->Value.Buffer;
+ Count = OrderedListStatement->StorageWidth / sizeof (UINT8);
+ for (Index = 0; Index < Count; Index++) {
+ DEBUG ((DEBUG_ERROR, "%d ", Value8[Index]));
+ }
+ break;
+ }
+
+ DEBUG ((DEBUG_ERROR, "\n"));
+}
+
+/**
+ Convert HII value to the string in HII ordered list opcode. It's caller's
+ responsibility to free returned buffer using FreePool().
+
+ @param[in] Statement Statement private instance
+ @param[out] ReturnSize The size of returned array
+
+ @retval EFI_STRING_ID The string ID array for options in ordered list.
+
+**/
+EFI_STRING_ID *
+HiiValueToOrderedListOptionStringId (
+ IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement,
+ OUT UINTN *ReturnSize
+ )
+{
+ LIST_ENTRY *Link;
+ HII_QUESTION_OPTION *Option;
+ UINTN OptionCount;
+ EFI_STRING_ID *ReturnedArray;
+ UINTN Index;
+ UINT64 Value;
+
+ if (Statement == NULL || ReturnSize == NULL) {
+ return NULL;
+ }
+
+ *ReturnSize = 0;
+
+ if (Statement->HiiStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
+ return NULL;
+ }
+
+ if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
+ return NULL;
+ }
+
+ DEBUG_CODE (
+ DumpOrderedListValue (Statement->HiiStatement);
+ );
+
+ OptionCount = 0;
+ Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
+ while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
+ Option = HII_QUESTION_OPTION_FROM_LINK (Link);
+
+ ++OptionCount;
+
+ Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
+ }
+
+ *ReturnSize = OptionCount;
+ ReturnedArray = AllocatePool (sizeof (EFI_STRING_ID) * OptionCount);
+ if (ReturnedArray == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__));
+ *ReturnSize = 0;
+ return NULL;
+ }
+
+ for (Index = 0; Index < OptionCount; Index++) {
+ Value = OrderedListGetArrayData (Statement->HiiStatement->Value.Buffer, Statement->HiiStatement->Value.BufferValueType, Index);
+ ReturnedArray[Index] = OrderedListOptionValueToStringId (Statement->HiiStatement, Value);
+ }
+
+ return ReturnedArray;
+}
+
+/**
+ Convert HII string to the value in HII ordered list opcode.
+
+ @param[in] Statement Statement private instance
+ @param[in] Schema Schema string
+ @param[in] HiiString Input string
+ @param[out] Value Value returned
+
+ @retval EFI_SUCCESS HII value is returned successfully.
+ @retval Others Errors occur
+
+**/
+EFI_STATUS
+HiiStringToOrderedListOptionValue (
+ IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement,
+ IN CHAR8 *Schema,
+ IN EFI_STRING HiiString,
+ OUT UINT64 *Value
+ )
+{
+ LIST_ENTRY *Link;
+ HII_QUESTION_OPTION *Option;
+ EFI_STRING TmpString;
+ BOOLEAN Found;
+
+ if (Statement == NULL || IS_EMPTY_STRING (HiiString) || Value == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Value = 0;
+
+ if (Statement->HiiStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
+ return EFI_NOT_FOUND;
+ }
+
+ Found = FALSE;
+ Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
+ while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
+ Option = HII_QUESTION_OPTION_FROM_LINK (Link);
+
+ TmpString = HiiGetRedfishString (Statement->ParentForm->ParentFormset->HiiHandle, Schema, Option->Text);
+ if (TmpString != NULL) {
+ if (StrCmp (TmpString, HiiString) == 0) {
+ *Value = ExtendHiiValueToU64 (&Option->Value);
+ Found = TRUE;
+ }
+ FreePool (TmpString);
+ }
+
+ if (Found) {
+ return EFI_SUCCESS;
+ }
+
+ Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Convert input ascii string to unicode string. It's caller's
+ responsibility to free returned buffer using FreePool().
+
+ @param[in] AsciiString Ascii string to be converted.
+
+ @retval CHAR16 * Unicode string on return.
+
+**/
+EFI_STRING
+StrToUnicodeStr (
+ IN CHAR8 *AsciiString
+ )
+{
+ UINTN StringLen;
+ EFI_STRING Buffer;
+ EFI_STATUS Status;
+
+ if (AsciiString == NULL || AsciiString[0] == '\0') {
+ return NULL;
+ }
+
+ StringLen = AsciiStrLen (AsciiString) + 1;
+ Buffer = AllocatePool (StringLen * sizeof (CHAR16));
+ if (Buffer == NULL) {
+ return NULL;
+ }
+
+ Status = AsciiStrToUnicodeStrS (AsciiString, Buffer, StringLen);
+ if (EFI_ERROR (Status)) {
+ FreePool (Buffer);
+ return NULL;
+ }
+
+ return Buffer;
+}
+
+/**
+ Return the full Redfish schema string from the given Schema and Version.
+
+ Returned schema string is: Schema + '.' + Version
+
+ @param[in] Schema Schema string
+ @param[in] Version Schema version string
+
+ @retval CHAR8 * Schema string. NULL when errors occur.
+
+**/
+CHAR8 *
+GetFullSchemaString (
+ IN CHAR8 *Schema,
+ IN CHAR8 *Version
+ )
+{
+ UINTN Size;
+ CHAR8 *FullName;
+
+ if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version)) {
+ return NULL;
+ }
+
+ Size = AsciiStrSize(CONFIGURE_LANGUAGE_PREFIX) + AsciiStrSize (Schema) + AsciiStrSize (Version);
+
+ FullName = AllocatePool (Size);
+ if (FullName == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, out-of-resource\n", __FUNCTION__));
+ return NULL;
+ }
+
+ AsciiSPrint (FullName, Size, "%a%a.%a", CONFIGURE_LANGUAGE_PREFIX, Schema, Version);
+
+ return FullName;
+}
+
+/**
+ Common implementation to get statement private instance.
+
+ @param[in] RedfishPlatformConfigPrivate Private instance.
+ @param[in] Schema Redfish schema string.
+ @param[in] ConfigureLang Configure language that refers to this statement.
+ @param[out] Statement Statement instance
+
+ @retval EFI_SUCCESS HII value is returned successfully.
+ @retval Others Errors occur
+
+**/
+EFI_STATUS
+RedfishPlatformConfigGetStatementCommon (
+ IN REDFISH_PLATFORM_CONFIG_PRIVATE *RedfishPlatformConfigPrivate,
+ IN CHAR8 *Schema,
+ IN EFI_STRING ConfigureLang,
+ OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE **Statement
+ )
+{
+ EFI_STATUS Status;
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
+
+ if (RedfishPlatformConfigPrivate == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (ConfigureLang) || Statement == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Statement = NULL;
+
+ Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList, &RedfishPlatformConfigPrivate->PendingList);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+
+ TargetStatement = GetStatementPrivateByConfigureLang (&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
+ if (TargetStatement == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, No match HII statement is found by the given %s in schema %a\n", __FUNCTION__, ConfigureLang, Schema));
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Find current HII question value.
+ //
+ Status = GetQuestionValue (
+ TargetStatement->ParentForm->ParentFormset->HiiFormSet,
+ TargetStatement->ParentForm->HiiForm,
+ TargetStatement->HiiStatement,
+ GetSetValueWithHiiDriver
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to get question current value: %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+
+
+ if (TargetStatement->HiiStatement->Value.Type == EFI_IFR_TYPE_UNDEFINED) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Return Value.
+ //
+ *Statement = TargetStatement;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Get Redfish value with the given Schema and Configure Language.
+
+ @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+ @param[in] Schema The Redfish schema to query.
+ @param[in] Version The Redfish version to query.
+ @param[in] ConfigureLang The target value which match this configure Language.
+ @param[out] Value The returned value.
+
+ @retval EFI_SUCCESS Value is returned successfully.
+ @retval Others Some error happened.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformConfigProtocolGetValue (
+ IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+ IN CHAR8 *Schema,
+ IN CHAR8 *Version,
+ IN EFI_STRING ConfigureLang,
+ OUT EDKII_REDFISH_VALUE *Value
+ )
+{
+ EFI_STATUS Status;
+ REDFISH_PLATFORM_CONFIG_PRIVATE *RedfishPlatformConfigPrivate;
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
+ EFI_STRING_ID StringId;
+ EFI_STRING_ID *StringIdArray;
+ CHAR8 *FullSchema;
+ EFI_STRING HiiString;
+ UINTN Count;
+ UINTN Index;
+
+ if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || IS_EMPTY_STRING (ConfigureLang) || Value == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
+ Value->Type = REDFISH_VALUE_TYPE_UNKNOWN;
+ Value->ArrayCount = 0;
+ Count = 0;
+ FullSchema = NULL;
+ HiiString = NULL;
+ StringIdArray = NULL;
+
+ FullSchema = GetFullSchemaString (Schema, Version);
+ if (FullSchema == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = RedfishPlatformConfigGetStatementCommon (RedfishPlatformConfigPrivate, FullSchema, ConfigureLang, &TargetStatement);
+ if (EFI_ERROR (Status)) {
+ goto RELEASE_RESOURCE;
+ }
+
+ switch (TargetStatement->HiiStatement->Operand) {
+ case EFI_IFR_ONE_OF_OP:
+ StringId = HiiValueToOneOfOptionStringId (TargetStatement);
+ if (StringId == 0) {
+ ASSERT (FALSE);
+ Status = EFI_DEVICE_ERROR;
+ goto RELEASE_RESOURCE;
+ }
+
+ Value->Value.Buffer = HiiGetRedfishAsciiString (TargetStatement->ParentForm->ParentFormset->HiiHandle, FullSchema, StringId);
+ if (Value->Value.Buffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto RELEASE_RESOURCE;
+ }
+
+ Value->Type = REDFISH_VALUE_TYPE_STRING;
+ break;
+ case EFI_IFR_STRING_OP:
+ if (TargetStatement->HiiStatement->Value.Type != EFI_IFR_TYPE_STRING) {
+ ASSERT (FALSE);
+ Status = EFI_DEVICE_ERROR;
+ goto RELEASE_RESOURCE;
+ }
+
+ Value->Type = REDFISH_VALUE_TYPE_STRING;
+ Value->Value.Buffer = AllocatePool (StrLen ((CHAR16 *)TargetStatement->HiiStatement->Value.Buffer) + 1);
+ UnicodeStrToAsciiStrS ((CHAR16 *)TargetStatement->HiiStatement->Value.Buffer, Value->Value.Buffer, StrLen ((CHAR16 *)TargetStatement->HiiStatement->Value.Buffer) + 1);
+ break;
+ case EFI_IFR_CHECKBOX_OP:
+ case EFI_IFR_NUMERIC_OP:
+ Status = HiiValueToRedfishNumeric (&TargetStatement->HiiStatement->Value, Value);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to convert HII value to Redfish value: %r\n", __FUNCTION__, Status));
+ goto RELEASE_RESOURCE;
+ }
+ break;
+ case EFI_IFR_ACTION_OP:
+ if (TargetStatement->HiiStatement->Value.Type != EFI_IFR_TYPE_ACTION) {
+ ASSERT (FALSE);
+ Status = EFI_DEVICE_ERROR;
+ goto RELEASE_RESOURCE;
+ }
+
+ //
+ // Action has no value. Just return unknown type.
+ //
+ Value->Type = REDFISH_VALUE_TYPE_UNKNOWN;
+ break;
+ case EFI_IFR_ORDERED_LIST_OP:
+ StringIdArray = HiiValueToOrderedListOptionStringId (TargetStatement, &Count);
+ if (StringIdArray == NULL) {
+ ASSERT (FALSE);
+ Status = EFI_DEVICE_ERROR;
+ goto RELEASE_RESOURCE;
+ }
+
+ Value->Value.StringArray = AllocatePool (sizeof (CHAR8 *) * Count);
+ if (Value->Value.StringArray == NULL) {
+ ASSERT (FALSE);
+ Status = EFI_OUT_OF_RESOURCES;
+ goto RELEASE_RESOURCE;
+ }
+
+ for (Index = 0; Index < Count; Index++) {
+ ASSERT (StringIdArray[Index] != 0);
+ Value->Value.StringArray[Index] = HiiGetRedfishAsciiString (TargetStatement->ParentForm->ParentFormset->HiiHandle, FullSchema, StringIdArray[Index]);
+ }
+
+ Value->ArrayCount = Count;
+ Value->Type = REDFISH_VALUE_TYPE_STRING_ARRAY;
+ break;
+ default:
+ DEBUG ((DEBUG_ERROR, "%a, catch unsupported type: 0x%x! Please contact with author if we need to support this type.\n", __FUNCTION__, TargetStatement->HiiStatement->Operand));
+ ASSERT (FALSE);
+ Status = EFI_UNSUPPORTED;
+ goto RELEASE_RESOURCE;
+ }
+
+RELEASE_RESOURCE:
+
+ if (FullSchema != NULL) {
+ FreePool (FullSchema);
+ }
+
+ if (HiiString != NULL) {
+ FreePool (HiiString);
+ }
+
+ if (StringIdArray != NULL) {
+ FreePool (StringIdArray);
+ }
+
+ return Status;
+}
+
+/**
+ Function to save question value into HII database.
+
+ @param[in] HiiFormset HII form-set instance
+ @param[in] HiiForm HII form instance
+ @param[in] HiiStatement HII statement that keeps new value.
+ @param[in] Value New value to applyu.
+
+ @retval EFI_SUCCESS HII value is returned successfully.
+ @retval Others Errors occur
+
+**/
+EFI_STATUS
+RedfishPlatformConfigSaveQuestionValue (
+ IN HII_FORMSET *HiiFormset,
+ IN HII_FORM *HiiForm,
+ IN HII_STATEMENT *HiiStatement,
+ IN HII_STATEMENT_VALUE *Value
+ )
+{
+ EFI_STATUS Status;
+
+ if (HiiFormset == NULL || HiiForm == NULL || HiiStatement == NULL || Value == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = SetQuestionValue (
+ HiiFormset,
+ HiiForm,
+ HiiStatement,
+ Value
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to set question value: %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+
+ Status = SubmitForm (HiiFormset, HiiForm);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to submit form: %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Common implementation to set statement private instance.
+
+ @param[in] RedfishPlatformConfigPrivate Private instance.
+ @param[in] Schema Redfish schema string.
+ @param[in] ConfigureLang Configure language that refers to this statement.
+ @param[in] Statement Statement instance
+
+ @retval EFI_SUCCESS HII value is returned successfully.
+ @retval Others Errors occur
+
+**/
+EFI_STATUS
+RedfishPlatformConfigSetStatementCommon (
+ IN REDFISH_PLATFORM_CONFIG_PRIVATE *RedfishPlatformConfigPrivate,
+ IN CHAR8 *Schema,
+ IN EFI_STRING ConfigureLang,
+ IN HII_STATEMENT_VALUE *StatementValue
+ )
+{
+ EFI_STATUS Status;
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
+ EFI_STRING TempBuffer;
+ UINT8 *StringArray;
+ UINTN Index;
+ UINT64 Value;
+ CHAR8 **CharArray;
+
+ if (RedfishPlatformConfigPrivate == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (ConfigureLang) || StatementValue == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TempBuffer = NULL;
+ StringArray = NULL;
+
+ Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList, &RedfishPlatformConfigPrivate->PendingList);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+
+ TargetStatement = GetStatementPrivateByConfigureLang (&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
+ if (TargetStatement == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, No match HII statement is found by the given %s in schema %a\n", __FUNCTION__, ConfigureLang, Schema));
+ return EFI_NOT_FOUND;
+ }
+
+ if (StatementValue->Type != TargetStatement->HiiStatement->Value.Type) {
+ //
+ // We treat one-of type as string in Redfish. But one-of statement is not
+ // in string format from HII point of view. Do a patch here.
+ //
+ if (TargetStatement->HiiStatement->Operand == EFI_IFR_ONE_OF_OP && StatementValue->Type == EFI_IFR_TYPE_STRING) {
+
+ TempBuffer = StrToUnicodeStr ((CHAR8 *)StatementValue->Buffer);
+ if (TempBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ FreePool (StatementValue->Buffer);
+ StatementValue->Buffer = NULL;
+ StatementValue->BufferLen = 0;
+
+ Status = HiiStringToOneOfOptionValue (TargetStatement, Schema, TempBuffer, StatementValue);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to find option value by the given %s\n", __FUNCTION__, TempBuffer));
+ FreePool (TempBuffer);
+ return EFI_NOT_FOUND;
+ }
+
+ FreePool (TempBuffer);
+ } else if (TargetStatement->HiiStatement->Operand == EFI_IFR_ORDERED_LIST_OP && StatementValue->Type == EFI_IFR_TYPE_STRING) {
+ //
+ // We treat ordered list type as string in Redfish. But ordered list statement is not
+ // in string format from HII point of view. Do a patch here.
+ //
+ StringArray = AllocateZeroPool (TargetStatement->HiiStatement->StorageWidth);
+ if (StringArray == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Arrage new option order from input string array
+ //
+ CharArray = (CHAR8 **)StatementValue->Buffer;
+ for (Index = 0; Index < StatementValue->BufferLen; Index++) {
+ TempBuffer = StrToUnicodeStr (CharArray[Index]);
+ if (TempBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = HiiStringToOrderedListOptionValue (TargetStatement, Schema, TempBuffer, &Value);
+ if (EFI_ERROR (Status)) {
+ ASSERT (FALSE);
+ continue;
+ }
+ FreePool (TempBuffer);
+ OrderedListSetArrayData (StringArray, TargetStatement->HiiStatement->Value.BufferValueType, Index, Value);
+ }
+
+ StatementValue->Type = EFI_IFR_TYPE_BUFFER;
+ StatementValue->Buffer = StringArray;
+ StatementValue->BufferLen = TargetStatement->HiiStatement->StorageWidth;
+ StatementValue->BufferValueType = TargetStatement->HiiStatement->Value.BufferValueType;
+ } else if (TargetStatement->HiiStatement->Operand == EFI_IFR_NUMERIC_OP && StatementValue->Type == EFI_IFR_TYPE_NUM_SIZE_64) {
+ //
+ // Redfish only has numeric value type and it does not care about the value size.
+ // Do a patch here so we have proper value size applied.
+ //
+ StatementValue->Type = TargetStatement->HiiStatement->Value.Type;
+ } else {
+ DEBUG ((DEBUG_ERROR, "%a, catch value type mismatch! input type: 0x%x but target value type: 0x%x\n", __FUNCTION__, StatementValue->Type, TargetStatement->HiiStatement->Value.Type));
+ ASSERT (FALSE);
+ }
+ }
+
+ Status = RedfishPlatformConfigSaveQuestionValue (
+ TargetStatement->ParentForm->ParentFormset->HiiFormSet,
+ TargetStatement->ParentForm->HiiForm,
+ TargetStatement->HiiStatement,
+ StatementValue
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to save question value: %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Set Redfish value with the given Schema and Configure Language.
+
+ @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+ @param[in] Schema The Redfish schema to query.
+ @param[in] Version The Redfish version to query.
+ @param[in] ConfigureLang The target value which match this configure Language.
+ @param[in] Value The value to set.
+
+ @retval EFI_SUCCESS Value is returned successfully.
+ @retval Others Some error happened.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformConfigProtocolSetValue (
+ IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+ IN CHAR8 *Schema,
+ IN CHAR8 *Version,
+ IN EFI_STRING ConfigureLang,
+ IN EDKII_REDFISH_VALUE Value
+ )
+{
+ EFI_STATUS Status;
+ REDFISH_PLATFORM_CONFIG_PRIVATE *RedfishPlatformConfigPrivate;
+ CHAR8 *FullSchema;
+ HII_STATEMENT_VALUE NewValue;
+
+ if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || IS_EMPTY_STRING (ConfigureLang)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Value.Type == REDFISH_VALUE_TYPE_UNKNOWN || Value.Type >= REDFISH_VALUE_TYPE_MAX) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
+ FullSchema = NULL;
+
+ FullSchema = GetFullSchemaString (Schema, Version);
+ if (FullSchema == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ZeroMem (&NewValue, sizeof (HII_STATEMENT_VALUE));
+
+ switch (Value.Type) {
+ case REDFISH_VALUE_TYPE_INTEGER:
+ case REDFISH_VALUE_TYPE_BOOLEAN:
+ Status = RedfishNumericToHiiValue (&Value, &NewValue);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to convert Redfish value to Hii value: %r\n", __FUNCTION__, Status));
+ goto RELEASE_RESOURCE;
+ }
+ break;
+ case REDFISH_VALUE_TYPE_STRING:
+ NewValue.Type = EFI_IFR_TYPE_STRING;
+ NewValue.BufferLen = (UINT16)AsciiStrSize (Value.Value.Buffer);
+ NewValue.Buffer = AllocateCopyPool (NewValue.BufferLen, Value.Value.Buffer);
+ if (NewValue.Buffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto RELEASE_RESOURCE;
+ }
+ break;
+ case REDFISH_VALUE_TYPE_STRING_ARRAY:
+ NewValue.Type = EFI_IFR_TYPE_STRING;
+ NewValue.BufferLen = (UINT16)Value.ArrayCount;
+ NewValue.Buffer = (UINT8 *)Value.Value.StringArray;
+ break;
+ default:
+ ASSERT (FALSE);
+ break;
+ }
+
+ Status = RedfishPlatformConfigSetStatementCommon (RedfishPlatformConfigPrivate, FullSchema, ConfigureLang, &NewValue);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to set value to statement: %r\n", __FUNCTION__, Status));
+ }
+
+RELEASE_RESOURCE:
+
+ if (FullSchema != NULL) {
+ FreePool (FullSchema);
+ }
+
+ return Status;
+}
+
+/**
+ Get the list of Configure Language from platform configuration by the given Schema and RegexPattern.
+
+ @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+ @param[in] Schema The Redfish schema to query.
+ @param[in] Version The Redfish version to query.
+ @param[in] RegexPattern The target Configure Language pattern. This is used for regular expression matching.
+ @param[out] ConfigureLangList The list of Configure Language.
+ @param[out] Count The number of Configure Language in ConfigureLangList.
+
+ @retval EFI_SUCCESS ConfigureLangList is returned successfully.
+ @retval Others Some error happened.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformConfigProtocolGetConfigureLang (
+ IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+ IN CHAR8 *Schema,
+ IN CHAR8 *Version,
+ IN EFI_STRING RegexPattern,
+ OUT EFI_STRING **ConfigureLangList,
+ OUT UINTN *Count
+ )
+{
+ REDFISH_PLATFORM_CONFIG_PRIVATE *RedfishPlatformConfigPrivate;
+ EFI_STATUS Status;
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST StatementList;
+ REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF *StatementRef;
+ LIST_ENTRY *NextLink;
+ EFI_STRING TmpString;
+ EFI_STRING *TmpConfigureLangList;
+ UINTN Index;
+ CHAR8 *FullSchema;
+
+ if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || Count == NULL || ConfigureLangList == NULL || IS_EMPTY_STRING (RegexPattern)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Count = 0;
+ *ConfigureLangList = NULL;
+ FullSchema = NULL;
+ RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
+
+ Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList, &RedfishPlatformConfigPrivate->PendingList);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+
+ FullSchema = GetFullSchemaString (Schema, Version);
+ if (FullSchema == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = GetStatementPrivateByConfigureLangRegex (
+ RedfishPlatformConfigPrivate->RegularExpressionProtocol,
+ &RedfishPlatformConfigPrivate->FormsetList,
+ FullSchema,
+ RegexPattern,
+ &StatementList
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, GetStatementPrivateByConfigureLangRegex failure: %r\n", __FUNCTION__, Status));
+ goto RELEASE_RESOURCE;
+ }
+
+ if (!IsListEmpty (&StatementList.StatementList)) {
+
+ TmpConfigureLangList = AllocateZeroPool (sizeof (CHAR16 *) * StatementList.Count);
+ if (TmpConfigureLangList == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto RELEASE_RESOURCE;
+ }
+
+ Index = 0;
+ NextLink = GetFirstNode (&StatementList.StatementList);
+ while (!IsNull (&StatementList.StatementList, NextLink)) {
+ StatementRef = REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
+ NextLink = GetNextNode (&StatementList.StatementList, NextLink);
+
+ ASSERT (StatementRef->Statement->Description != 0);
+ if (StatementRef->Statement->Description != 0) {
+ TmpString = HiiGetRedfishString (StatementRef->Statement->ParentForm->ParentFormset->HiiHandle, FullSchema, StatementRef->Statement->Description);
+ ASSERT (TmpString != NULL);
+ if (TmpString != NULL) {
+ TmpConfigureLangList[Index] = AllocateCopyPool (StrSize (TmpString), TmpString);
+ ASSERT (TmpConfigureLangList[Index] != NULL);
+ FreePool (TmpString);
+ ++Index;
+ }
+ }
+ }
+ }
+
+ *Count = StatementList.Count;
+ *ConfigureLangList = TmpConfigureLangList;
+
+RELEASE_RESOURCE:
+
+ if (FullSchema != NULL) {
+ FreePool (FullSchema);
+ }
+
+ ReleaseStatementList (&StatementList);
+
+ return Status;
+}
+
+/**
+ Get the list of supported Redfish schema from paltform configuration on give HII handle.
+
+ @param[in] This Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+ @param[in] HiiHandle The target handle to search. If handle is NULL,
+ this function return all schema from HII database.
+ @param[out] SupportedSchema The supported schema list which is separated by ';'.
+ The SupportedSchema is allocated by the callee. It's caller's
+ responsibility to free this buffer using FreePool().
+
+ @retval EFI_SUCCESS Schema is returned successfully.
+ @retval Others Some error happened.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformConfigProtocolGetSupportedSchema (
+ IN EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+ IN EFI_HII_HANDLE HiiHandle, OPTIONAL
+ OUT CHAR8 **SupportedSchema
+ )
+{
+ REDFISH_PLATFORM_CONFIG_PRIVATE *RedfishPlatformConfigPrivate;
+ EFI_STATUS Status;
+ LIST_ENTRY *HiiFormsetLink;
+ LIST_ENTRY *HiiFormsetNextLink;
+ REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
+ UINTN Index;
+ UINTN StringSize;
+ CHAR8 *StringBuffer;
+ UINTN StringIndex;
+
+ if (This == NULL || SupportedSchema == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *SupportedSchema = NULL;
+
+ RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
+
+ Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList, &RedfishPlatformConfigPrivate->PendingList);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+
+ if (IsListEmpty (&RedfishPlatformConfigPrivate->FormsetList)) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Calculate for string buffer size.
+ //
+ StringSize = 0;
+ HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate->FormsetList);
+ while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLink)) {
+ HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLink);
+ HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+ if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
+ HiiFormsetLink = HiiFormsetNextLink;
+ continue;
+ }
+
+ if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
+ for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count; Index++) {
+ StringSize += AsciiStrSize (HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
+ }
+ }
+
+ HiiFormsetLink = HiiFormsetNextLink;
+ }
+
+ if (StringSize == 0) {
+ return EFI_NOT_FOUND;
+ }
+
+ StringBuffer = AllocatePool (StringSize);
+ if (StringBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ StringIndex = 0;
+ HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate->FormsetList);
+ while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLink)) {
+ HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLink);
+ HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+ if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
+ HiiFormsetLink = HiiFormsetNextLink;
+ continue;
+ }
+
+ if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
+ for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count; Index++) {
+ AsciiStrCpyS (&StringBuffer[StringIndex], (StringSize - StringIndex), HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
+ StringIndex += AsciiStrLen (HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
+ StringBuffer[StringIndex] = ';';
+ ++StringIndex;
+ }
+ }
+
+ HiiFormsetLink = HiiFormsetNextLink;
+ }
+
+ StringBuffer[--StringIndex] = '\0';
+
+ *SupportedSchema = StringBuffer;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Functions which are registered to receive notification of
+ database events have this prototype. The actual event is encoded
+ in NotifyType. The following table describes how PackageType,
+ PackageGuid, Handle, and Package are used for each of the
+ notification types.
+
+ @param[in] PackageType Package type of the notification.
+ @param[in] PackageGuid If PackageType is
+ EFI_HII_PACKAGE_TYPE_GUID, then this is
+ the pointer to the GUID from the Guid
+ field of EFI_HII_PACKAGE_GUID_HEADER.
+ Otherwise, it must be NULL.
+ @param[in] Package Points to the package referred to by the
+ notification Handle The handle of the package
+ list which contains the specified package.
+ @param[in] Handle The HII handle.
+ @param[in] NotifyType The type of change concerning the
+ database. See
+ EFI_HII_DATABASE_NOTIFY_TYPE.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformConfigFormUpdateNotify (
+ IN UINT8 PackageType,
+ IN CONST EFI_GUID *PackageGuid,
+ IN CONST EFI_HII_PACKAGE_HEADER *Package,
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
+ )
+{
+ EFI_STATUS Status;
+
+ if (NotifyType == EFI_HII_DATABASE_NOTIFY_NEW_PACK || NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
+ //
+ // HII formset on this handle is updated by driver during run-time. The formset needs to be reloaded.
+ //
+ Status = NotifyFormsetUpdate (Handle, &mRedfishPlatformConfigPrivate->PendingList);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to notify updated formset of HII handle: 0x%x\n", __FUNCTION__, Handle));
+ return Status;
+ }
+ } else if (NotifyType == EFI_HII_DATABASE_NOTIFY_REMOVE_PACK) {
+ //
+ // HII resource is removed. The formset is no longer exist.
+ //
+ Status = NotifyFormsetDeleted (Handle, &mRedfishPlatformConfigPrivate->PendingList);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to notify deleted formset of HII handle: 0x%x\n", __FUNCTION__, Handle));
+ return Status;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This is a EFI_HII_STRING_PROTOCOL notification event handler.
+
+ Install HII package notification.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context Pointer to the notification function's context.
+
+**/
+VOID
+EFIAPI
+HiiStringProtocolInstalled (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Locate HII database protocol.
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiHiiStringProtocolGuid,
+ NULL,
+ (VOID **)&mRedfishPlatformConfigPrivate->HiiString
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, locate EFI_HII_STRING_PROTOCOL failure: %r\n", __FUNCTION__, Status));
+ return;
+ }
+
+ gBS->CloseEvent (Event);
+ mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent = NULL;
+}
+
+/**
+ This is a EFI_HII_DATABASE_PROTOCOL notification event handler.
+
+ Install HII package notification.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context Pointer to the notification function's context.
+
+**/
+VOID
+EFIAPI
+HiiDatabaseProtocolInstalled (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Locate HII database protocol.
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiHiiDatabaseProtocolGuid,
+ NULL,
+ (VOID **)&mRedfishPlatformConfigPrivate->HiiDatabase
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, locate EFI_HII_DATABASE_PROTOCOL failure: %r\n", __FUNCTION__, Status));
+ return;
+ }
+
+ //
+ // Register package notification when new form package is installed.
+ //
+ Status = mRedfishPlatformConfigPrivate->HiiDatabase->RegisterPackageNotify (
+ mRedfishPlatformConfigPrivate->HiiDatabase,
+ EFI_HII_PACKAGE_FORMS,
+ NULL,
+ RedfishPlatformConfigFormUpdateNotify,
+ EFI_HII_DATABASE_NOTIFY_NEW_PACK,
+ &mRedfishPlatformConfigPrivate->NotifyHandle
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__, Status));
+ }
+
+ //
+ // Register package notification when new form package is updated.
+ //
+ Status = mRedfishPlatformConfigPrivate->HiiDatabase->RegisterPackageNotify (
+ mRedfishPlatformConfigPrivate->HiiDatabase,
+ EFI_HII_PACKAGE_FORMS,
+ NULL,
+ RedfishPlatformConfigFormUpdateNotify,
+ EFI_HII_DATABASE_NOTIFY_ADD_PACK,
+ &mRedfishPlatformConfigPrivate->NotifyHandle
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__, Status));
+ }
+
+ gBS->CloseEvent (Event);
+ mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent = NULL;
+
+}
+
+/**
+ This is a EFI_REGULAR_EXPRESSION_PROTOCOL notification event handler.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context Pointer to the notification function's context.
+
+**/
+VOID
+EFIAPI
+RegexProtocolInstalled (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Locate regular expression protocol.
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiRegularExpressionProtocolGuid,
+ NULL,
+ (VOID **)&mRedfishPlatformConfigPrivate->RegularExpressionProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, locate EFI_REGULAR_EXPRESSION_PROTOCOL failure: %r\n", __FUNCTION__, Status));
+ return;
+ }
+
+ gBS->CloseEvent (Event);
+ mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent = NULL;
+
+}
+
+/**
+ Unloads an image.
+
+ @param ImageHandle Handle that identifies the image to be unloaded.
+
+ @retval EFI_SUCCESS The image has been unloaded.
+ @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformConfigDxeUnload (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+
+ if (mRedfishPlatformConfigPrivate != NULL) {
+ Status = gBS->UninstallProtocolInterface (
+ mRedfishPlatformConfigPrivate->ImageHandle,
+ &gEdkIIRedfishPlatformConfigProtocolGuid,
+ (VOID*)&mRedfishPlatformConfigPrivate->Protocol
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, can not uninstall gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
+ ASSERT (FALSE);
+ }
+
+ //
+ // Close events
+ //
+ if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent != NULL) {
+ gBS->CloseEvent (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent);
+ }
+ if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent != NULL) {
+ gBS->CloseEvent (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent);
+ }
+ if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent != NULL) {
+ gBS->CloseEvent (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent);
+ }
+
+ //
+ // Unregister package notification.
+ //
+ if (mRedfishPlatformConfigPrivate->NotifyHandle != NULL) {
+ mRedfishPlatformConfigPrivate->HiiDatabase->UnregisterPackageNotify (
+ mRedfishPlatformConfigPrivate->HiiDatabase,
+ mRedfishPlatformConfigPrivate->NotifyHandle
+ );
+ }
+
+ ReleaseFormsetList (&mRedfishPlatformConfigPrivate->FormsetList);
+ FreePool (mRedfishPlatformConfigPrivate);
+ mRedfishPlatformConfigPrivate = NULL;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This is the declaration of an EFI image entry point. This entry point is
+ the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
+ both device drivers and bus drivers.
+
+ @param ImageHandle The firmware allocated handle for the UEFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval Others An unexpected error occurred.
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformConfigDxeEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ mRedfishPlatformConfigPrivate = (REDFISH_PLATFORM_CONFIG_PRIVATE *)AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PRIVATE));
+ if (mRedfishPlatformConfigPrivate == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, can not allocate pool for REDFISH_PLATFORM_CONFIG_PRIVATE\n", __FUNCTION__));
+ ASSERT (FALSE);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Protocol initialization
+ //
+ mRedfishPlatformConfigPrivate->ImageHandle = ImageHandle;
+ mRedfishPlatformConfigPrivate->Protocol.GetValue = RedfishPlatformConfigProtocolGetValue;
+ mRedfishPlatformConfigPrivate->Protocol.SetValue = RedfishPlatformConfigProtocolSetValue;
+ mRedfishPlatformConfigPrivate->Protocol.GetConfigureLang = RedfishPlatformConfigProtocolGetConfigureLang;
+ mRedfishPlatformConfigPrivate->Protocol.GetSupportedSchema = RedfishPlatformConfigProtocolGetSupportedSchema;
+
+ InitializeListHead (&mRedfishPlatformConfigPrivate->FormsetList);
+ InitializeListHead (&mRedfishPlatformConfigPrivate->PendingList);
+
+ Status = gBS->InstallProtocolInterface (
+ &ImageHandle,
+ &gEdkIIRedfishPlatformConfigProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ (VOID*)&mRedfishPlatformConfigPrivate->Protocol
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a, can not install gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
+ ASSERT (FALSE);
+ }
+
+ //
+ // Install protocol notification if HII database protocol is installed.
+ //
+ mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent = EfiCreateProtocolNotifyEvent (
+ &gEfiHiiDatabaseProtocolGuid,
+ TPL_CALLBACK,
+ HiiDatabaseProtocolInstalled,
+ NULL,
+ &mRedfishPlatformConfigPrivate->HiiDbNotify.Registration
+ );
+ if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for gEfiHiiDatabaseProtocolGuid\n", __FUNCTION__));
+ ASSERT (FALSE);
+ }
+
+ //
+ // Install protocol notification if HII string protocol is installed.
+ //
+ mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent = EfiCreateProtocolNotifyEvent (
+ &gEfiHiiStringProtocolGuid,
+ TPL_CALLBACK,
+ HiiStringProtocolInstalled,
+ NULL,
+ &mRedfishPlatformConfigPrivate->HiiStringNotify.Registration
+ );
+ if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for gEfiHiiStringProtocolGuid\n", __FUNCTION__));
+ ASSERT (FALSE);
+ }
+
+ //
+ // Install protocol notification if regular expression protocol is installed.
+ //
+ mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent = EfiCreateProtocolNotifyEvent (
+ &gEfiRegularExpressionProtocolGuid,
+ TPL_CALLBACK,
+ RegexProtocolInstalled,
+ NULL,
+ &mRedfishPlatformConfigPrivate->RegexNotify.Registration
+ );
+ if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for gEfiRegularExpressionProtocolGuid\n", __FUNCTION__));
+ ASSERT (FALSE);
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
index 99a613d229..d3f7af55ad 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
@@ -1,64 +1,64 @@
-/** @file
- This file defines the EDKII Redfish Platform Config Protocol interface.
-
- (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
-#define EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
-
-#include <Uefi.h>
-
-//
-// Libraries
-//
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/PrintLib.h>
-#include <Library/UefiLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiDriverEntryPoint.h>
-
-//
-// Produced Protocols
-//
-#include <Protocol/EdkIIRedfishPlatformConfig.h>
-#include <Protocol/HiiDatabase.h>
-#include <Protocol/HiiString.h>
-#include <Protocol/RegularExpressionProtocol.h>
-
-//
-// Definition of EDKII_REDFISH_PLATFORM_CONFIG_NOTIFY.
-//
-typedef struct {
- EFI_EVENT ProtocolEvent; // Protocol notification event.
- VOID *Registration; // Protocol notification registration.
-} REDFISH_PLATFORM_CONFIG_NOTIFY;
-
-//
-// Definition of REDFISH_PLATFORM_CONFIG_PRIVATE.
-//
-typedef struct {
- EFI_HANDLE ImageHandle; // Driver image handle.
- EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL Protocol;
- REDFISH_PLATFORM_CONFIG_NOTIFY HiiDbNotify;
- EFI_HII_DATABASE_PROTOCOL *HiiDatabase; // The HII database protocol.
- REDFISH_PLATFORM_CONFIG_NOTIFY HiiStringNotify;
- EFI_HII_STRING_PROTOCOL *HiiString; // HII String Protocol.
- REDFISH_PLATFORM_CONFIG_NOTIFY RegexNotify;
- EFI_REGULAR_EXPRESSION_PROTOCOL *RegularExpressionProtocol; // Regular Expression Protocol.
- EFI_HANDLE NotifyHandle; // The notify handle.
- LIST_ENTRY FormsetList; // The list to keep cached HII formset.
- LIST_ENTRY PendingList; // The list to keep updated HII handle.
-} REDFISH_PLATFORM_CONFIG_PRIVATE;
-
-#define REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS(a) BASE_CR (a, REDFISH_PLATFORM_CONFIG_PRIVATE, Protocol)
-#define REGULAR_EXPRESSION_INCLUDE_ALL L".*"
-#define CONFIGURE_LANGUAGE_PREFIX "x-uefi-redfish-"
-
-#endif
+/** @file
+ This file defines the EDKII Redfish Platform Config Protocol interface.
+
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
+#define EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
+
+#include <Uefi.h>
+
+//
+// Libraries
+//
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+
+//
+// Produced Protocols
+//
+#include <Protocol/EdkIIRedfishPlatformConfig.h>
+#include <Protocol/HiiDatabase.h>
+#include <Protocol/HiiString.h>
+#include <Protocol/RegularExpressionProtocol.h>
+
+//
+// Definition of EDKII_REDFISH_PLATFORM_CONFIG_NOTIFY.
+//
+typedef struct {
+ EFI_EVENT ProtocolEvent; // Protocol notification event.
+ VOID *Registration; // Protocol notification registration.
+} REDFISH_PLATFORM_CONFIG_NOTIFY;
+
+//
+// Definition of REDFISH_PLATFORM_CONFIG_PRIVATE.
+//
+typedef struct {
+ EFI_HANDLE ImageHandle; // Driver image handle.
+ EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL Protocol;
+ REDFISH_PLATFORM_CONFIG_NOTIFY HiiDbNotify;
+ EFI_HII_DATABASE_PROTOCOL *HiiDatabase; // The HII database protocol.
+ REDFISH_PLATFORM_CONFIG_NOTIFY HiiStringNotify;
+ EFI_HII_STRING_PROTOCOL *HiiString; // HII String Protocol.
+ REDFISH_PLATFORM_CONFIG_NOTIFY RegexNotify;
+ EFI_REGULAR_EXPRESSION_PROTOCOL *RegularExpressionProtocol; // Regular Expression Protocol.
+ EFI_HANDLE NotifyHandle; // The notify handle.
+ LIST_ENTRY FormsetList; // The list to keep cached HII formset.
+ LIST_ENTRY PendingList; // The list to keep updated HII handle.
+} REDFISH_PLATFORM_CONFIG_PRIVATE;
+
+#define REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS(a) BASE_CR (a, REDFISH_PLATFORM_CONFIG_PRIVATE, Protocol)
+#define REGULAR_EXPRESSION_INCLUDE_ALL L".*"
+#define CONFIGURE_LANGUAGE_PREFIX "x-uefi-redfish-"
+
+#endif
diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf
index 16739bef7a..81b22e03c3 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf
@@ -1,53 +1,53 @@
-## @file
-# Implementation of EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL interfaces.
-#
-# (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = RedfishPlatformConfigDxe
- FILE_GUID = BEAEFFE1-0633-41B5-913C-9389339C2927
- MODULE_TYPE = DXE_DRIVER
- VERSION_STRING = 1.0
- ENTRY_POINT = RedfishPlatformConfigDxeEntryPoint
- UNLOAD_IMAGE = RedfishPlatformConfigDxeUnload
-
-[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
- RedfishPkg/RedfishPkg.dec
-
-[Sources]
- RedfishPlatformConfigDxe.h
- RedfishPlatformConfigDxe.c
- RedfishPlatformConfigImpl.h
- RedfishPlatformConfigImpl.c
-
-[LibraryClasses]
- BaseLib
- BaseMemoryLib
- DebugLib
- DevicePathLib
- HiiLib
- HiiUtilityLib
- MemoryAllocationLib
- PrintLib
- UefiLib
- UefiBootServicesTableLib
- UefiRuntimeServicesTableLib
- UefiDriverEntryPoint
-
-[Protocols]
- gEdkIIRedfishPlatformConfigProtocolGuid ## PRODUCED
- gEfiHiiDatabaseProtocolGuid ## CONSUMED
- gEfiHiiStringProtocolGuid ## CONSUMED
- gEfiRegularExpressionProtocolGuid ## CONSUMED
-
-[Guids]
- gEfiRegexSyntaxTypePerlGuid ## CONSUMED
-
-[Depex]
+## @file
+# Implementation of EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL interfaces.
+#
+# (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = RedfishPlatformConfigDxe
+ FILE_GUID = BEAEFFE1-0633-41B5-913C-9389339C2927
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = RedfishPlatformConfigDxeEntryPoint
+ UNLOAD_IMAGE = RedfishPlatformConfigDxeUnload
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ RedfishPkg/RedfishPkg.dec
+
+[Sources]
+ RedfishPlatformConfigDxe.h
+ RedfishPlatformConfigDxe.c
+ RedfishPlatformConfigImpl.h
+ RedfishPlatformConfigImpl.c
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ DevicePathLib
+ HiiLib
+ HiiUtilityLib
+ MemoryAllocationLib
+ PrintLib
+ UefiLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+ UefiDriverEntryPoint
+
+[Protocols]
+ gEdkIIRedfishPlatformConfigProtocolGuid ## PRODUCED
+ gEfiHiiDatabaseProtocolGuid ## CONSUMED
+ gEfiHiiStringProtocolGuid ## CONSUMED
+ gEfiRegularExpressionProtocolGuid ## CONSUMED
+
+[Guids]
+ gEfiRegexSyntaxTypePerlGuid ## CONSUMED
+
+[Depex]
TRUE
\ No newline at end of file
diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
index d9eab6c883..525e666b6c 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
@@ -1,1240 +1,1288 @@
-/** @file
-
- The implementation of EDKII Redfidh Platform Config Protocol.
-
- (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-#include "RedfishPlatformConfigDxe.h"
-#include "RedfishPlatformConfigImpl.h"
-
-extern REDFISH_PLATFORM_CONFIG_PRIVATE *mRedfishPlatformConfigPrivate;
-
-/**
- Debug dump HII string
-
- @param[in] HiiHandle HII handle instance
- @param[in] StringId HII string to dump
-
- @retval EFI_SUCCESS Dump HII string successfully
- @retval Others Errors occur
-
-**/
-EFI_STATUS
-DumpHiiString (
- IN EFI_HII_HANDLE HiiHandle,
- IN EFI_STRING_ID StringId
- )
-{
- EFI_STRING String;
-
- if (HiiHandle == NULL || StringId == 0) {
- DEBUG ((DEBUG_INFO, "???"));
- return EFI_INVALID_PARAMETER;
- }
-
- String = HiiGetString (HiiHandle, StringId, NULL);
- if (String == NULL) {
- return EFI_NOT_FOUND;
- }
-
- DEBUG ((DEBUG_INFO, "%s", String));
- FreePool (String);
-
- return EFI_SUCCESS;
-}
-
-/**
- Debug dump HII form-set data
-
- @param[in] FormsetPrivate HII form-set private instance.
-
- @retval EFI_SUCCESS Dump form-set successfully
- @retval Others Errors occur
-
-**/
-EFI_STATUS
-DumpFormset (
- IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate
- )
-{
- LIST_ENTRY *HiiFormLink;
- LIST_ENTRY *HiiNextFormLink;
- REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *HiiFormPrivate;
- LIST_ENTRY *HiiStatementLink;
- LIST_ENTRY *HiiNextStatementLink;
- REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *HiiStatementPrivate;
- UINTN Index;
-
- if (FormsetPrivate == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- Index = 0;
- HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
- while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
- HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink);
- HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList, HiiFormLink);
-
- DEBUG ((DEBUG_INFO, " [%d] form: %d title: ", ++Index, HiiFormPrivate->Id));
- DumpHiiString (FormsetPrivate->HiiHandle, HiiFormPrivate->Title);
- DEBUG ((DEBUG_INFO, "\n"));
-
- HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
- while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
- HiiStatementPrivate = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
- HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);
-
- DEBUG ((DEBUG_INFO, " QID: 0x%x Prompt: ", HiiStatementPrivate->QuestionId));
- DumpHiiString (FormsetPrivate->HiiHandle, HiiStatementPrivate->Description);
- DEBUG ((DEBUG_INFO, "\n"));
-
- HiiStatementLink = HiiNextStatementLink;
- }
-
- HiiFormLink = HiiNextFormLink;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Debug dump HII form-set list
-
- @param[in] FormsetList Form-set list instance
-
- @retval EFI_SUCCESS Dump list successfully
- @retval Others Errors occur
-
-**/
-EFI_STATUS
-DumpFormsetList (
- IN LIST_ENTRY *FormsetList
- )
-{
- LIST_ENTRY *HiiFormsetLink;
- LIST_ENTRY *HiiFormsetNextLink;
- REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *HiiFormsetPrivate;
- UINTN Index;
-
- if (FormsetList == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (IsListEmpty (FormsetList)) {
- DEBUG ((DEBUG_INFO, "%a, Empty formset list\n", __FUNCTION__));
- return EFI_SUCCESS;
- }
-
- Index = 0;
- HiiFormsetLink = GetFirstNode (FormsetList);
- while (!IsNull (FormsetList, HiiFormsetLink)) {
- HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
- HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
- DEBUG ((DEBUG_INFO, "[%d] HII Handle: 0x%x formset: %g at %s\n", ++Index, HiiFormsetPrivate->HiiHandle, &HiiFormsetPrivate->Guid, HiiFormsetPrivate->DevicePathStr));
- DumpFormset (HiiFormsetPrivate);
-
- HiiFormsetLink = HiiFormsetNextLink;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Retrieves a string from a string package in a English language. The
- returned string is allocated using AllocatePool(). The caller is responsible
- for freeing the allocated buffer using FreePool().
-
- If HiiHandle is NULL, then ASSERT().
- If StringId is 0, then ASSET.
-
- @param[in] HiiStringProtocol EFI_HII_STRING_PROTOCOL instance.
- @param[in] HiiHandle A handle that was previously registered in the HII Database.
- @param[in] StringId The identifier of the string to retrieved from the string
- package associated with HiiHandle.
-
- @retval NULL The string specified by StringId is not present in the string package.
- @retval Other The string was returned.
-
-**/
-EFI_STRING
-HiiGetRedfishString (
- IN EFI_HII_HANDLE HiiHandle,
- IN CHAR8 *Language,
- IN EFI_STRING_ID StringId
- )
-{
- EFI_STATUS Status;
- UINTN StringSize;
- CHAR16 TempString;
- EFI_STRING String;
-
- if (mRedfishPlatformConfigPrivate->HiiString == NULL || HiiHandle == NULL || StringId == 0 || IS_EMPTY_STRING (Language)) {
- ASSERT (FALSE);
- return NULL;
- }
-
- //
- // Retrieve the size of the string in the string package for the BestLanguage
- //
- StringSize = 0;
- Status = mRedfishPlatformConfigPrivate->HiiString->GetString (
- mRedfishPlatformConfigPrivate->HiiString,
- Language,
- HiiHandle,
- StringId,
- &TempString,
- &StringSize,
- NULL
- );
- //
- // If GetString() returns EFI_SUCCESS for a zero size,
- // then there are no supported languages registered for HiiHandle. If GetString()
- // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is not present
- // in the HII Database
- //
- if (Status != EFI_BUFFER_TOO_SMALL) {
- return NULL;
- }
-
- //
- // Allocate a buffer for the return string
- //
- String = AllocateZeroPool (StringSize);
- if (String == NULL) {
- return NULL;
- }
-
- //
- // Retrieve the string from the string package
- //
- Status = mRedfishPlatformConfigPrivate->HiiString->GetString (
- mRedfishPlatformConfigPrivate->HiiString,
- Language,
- HiiHandle,
- StringId,
- String,
- &StringSize,
- NULL
- );
- if (EFI_ERROR (Status)) {
- //
- // Free the buffer and return NULL if the supported languages can not be retrieved.
- //
- FreePool (String);
- String = NULL;
- }
-
- //
- // Return the Null-terminated Unicode string
- //
- return String;
-}
-
-/**
- Get string from HII database in English language.
-
- @param[in] HiiHandle A handle that was previously registered in the HII Database.
- @param[in] StringId The identifier of the string to retrieved from the string
- package associated with HiiHandle.
-
- @retval NULL The string specified by StringId is not present in the string package.
- @retval Other The string was returned.
-
-**/
-EFI_STRING
-HiiGetEnglishString (
- IN EFI_HII_HANDLE HiiHandle,
- IN EFI_STRING_ID StringId
- )
-{
- return HiiGetRedfishString (HiiHandle, ENGLISH_LANGUAGE_CODE, StringId);
-}
-
-/**
- Check and see if this is supported schema or not.
-
- @param[in] SupportedSchema The list of supported schema.
- @param[in] Schema Schema string to be checked.
-
- @retval BOOLEAN TRUE if this is supported schema. FALSE otherwise.
-
-**/
-BOOLEAN
-CheckSupportedSchema (
- IN REDFISH_PLATFORM_CONFIG_SCHEMA *SupportedSchema,
- IN CHAR8 *Schema
- )
-{
- UINTN Index;
-
- if (SupportedSchema == NULL || IS_EMPTY_STRING (Schema)) {
- return FALSE;
- }
-
- if (SupportedSchema->Count == 0) {
- return FALSE;
- }
-
- for (Index = 0; Index < SupportedSchema->Count; Index++) {
- if (AsciiStrCmp (SupportedSchema->SchemaList[Index], Schema) == 0) {
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-/**
- Get the list of supported schema from the given HII handle.
-
- @param[in] HiiHandle HII handle instance.
- @param[out] SupportedSchema Supported schema on this HII handle.
-
- @retval EFI_SUCCESS Schema list is returned.
- @retval EFI_INVALID_PARAMETER HiiHandle is NULL or SupportedSchema is NULL.
- @retval EFI_NOT_FOUND No supported schema found.
- @retval EFI_OUT_OF_RESOURCES System is out of memory.
-
-**/
-EFI_STATUS
-GetSupportedSchema (
- IN EFI_HII_HANDLE HiiHandle,
- OUT REDFISH_PLATFORM_CONFIG_SCHEMA *SupportedSchema
- )
-{
- CHAR8 *SupportedLanguages;
- UINTN Index;
- UINTN LangIndex;
- UINTN Count;
- UINTN StrSize;
- UINTN ListIndex;
-
- if (HiiHandle == NULL || SupportedSchema == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- SupportedSchema->Count = 0;
-
- SupportedLanguages = HiiGetSupportedLanguages (HiiHandle);
- if (SupportedLanguages == NULL) {
- return EFI_NOT_FOUND;
- }
-
- Index = 0;
- LangIndex = 0;
- Count = 0;
- while (TRUE) {
- if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] == '\0') {
- if (AsciiStrnCmp (&SupportedLanguages[LangIndex], X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
- ++Count;
- }
- LangIndex = Index + 1;
- }
-
- if (SupportedLanguages[Index] == '\0') {
- break;
- }
-
- ++Index;
- }
-
- if (Count == 0) {
- return EFI_NOT_FOUND;
- }
-
- SupportedSchema->Count = Count;
- SupportedSchema->SchemaList = AllocatePool (sizeof (CHAR8 *) * Count);
- if (SupportedSchema->SchemaList == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Index = 0;
- LangIndex = 0;
- ListIndex = 0;
- while (TRUE) {
-
- if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] == '\0') {
- if (AsciiStrnCmp (&SupportedLanguages[LangIndex], X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
- StrSize = Index - LangIndex;
- SupportedSchema->SchemaList[ListIndex] = AllocateCopyPool ((StrSize + 1), &SupportedLanguages[LangIndex]);
- SupportedSchema->SchemaList[ListIndex][StrSize] = '\0';
- ++ListIndex;
- }
-
- LangIndex = Index + 1;
- }
-
- if (SupportedLanguages[Index] == '\0') {
- break;
- }
-
- ++Index;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Search and find statement private instance by given regular expression patthern
- which describes the Configure Language.
-
- @param[in] RegularExpressionProtocol Regular express protocol.
- @param[in] FormsetList Form-set list to search.
- @param[in] Schema Schema to be matched.
- @param[in] Pattern Regular expression pattern.
- @param[out] StatementList Statement list that match above pattern.
-
- @retval EFI_SUCCESS Statement list is returned.
- @retval EFI_INVALID_PARAMETER Input parameter is NULL.
- @retval EFI_NOT_READY Regular express protocol is NULL.
- @retval EFI_NOT_FOUND No statement is found.
- @retval EFI_OUT_OF_RESOURCES System is out of memor