Date   

Re: [PATCH v10 0/5] Use RngLib instead of TimerLib for OpensslLib

Matthew Carlson
 

Just pinging this thread to see what needs to get done next. Thank you Liming for the reviewed by on the MdeModulePkg changes.

--
- Matthew Carlson


Re: [PATCH v6 00/14] Add the VariablePolicy feature

Bret Barkelew
 

Thanks for the update, Jian. Dandan has submitted RBs on another thread.

 

That leaves patches 06 and 11.

 

Next up, Jordan Justen. How’s it going, Jordan. We’ve never spoken directly (to my knowledge) and that’s a shame.

If you had to eat a single food for the rest of your life, what would it be and can I have a Reviewed-by?

Keep in mind that you probably don’t want it to be particularly strong flavors; it’s going to get disgusting eventually.

I’d probably go with some simple red beans and rice or something.

 

- Bret

 

From: Wang, Jian J
Sent: Sunday, September 13, 2020 11:42 PM
To: Bret Barkelew; devel@edk2.groups.io; bret@...; Bi, Dandan
Cc: Yao, Jiewen; Wu, Hao A; liming.gao; Justen, Jordan L; Laszlo Ersek; Ard Biesheuvel; Andrew Fish; Ni, Ray
Subject: [EXTERNAL] RE: [edk2-devel] [PATCH v6 00/14] Add the VariablePolicy feature

 

Hi Bret,

 

Sorry to hear the Seattle’s situation. I’ve been there for several times and love the city very much. Hope everything goes back normal soon.

 

And sorry for slow response. This patch series have been delegated to Dandan to review by Liming. She has completed security review from Intel perspective, and given back comments to you. It seems that you forgot to include her in the CC-list. Sorry I didn’t notice it and told her to do review in time. She’ll give comments ASAP.

 

Since MdeModulePkg is a huge package, I cannot do detail review for each patch for this package. And we have already modules reviewers designated . I think, usually, they should do the detailed review first. The package maintainer will do gate-keeper works as the last step. Correct me if any misunderstanding here.

 

Removed Chao from cc-list (his email is not valid) and added Dandan in loop.

 

Regards,

Jian

 

From: Bret Barkelew <Bret.Barkelew@...>
Sent: Friday, September 11, 2020 11:18 PM
To: devel@edk2.groups.io; bret@...; Wang, Jian J <jian.j.wang@...>
Cc: Yao, Jiewen <jiewen.yao@...>; Zhang, Chao B <chao.b.zhang@...>; Wang, Jian J <jian.j.wang@...>; Wu, Hao A <hao.a.wu@...>; Gao, Liming <liming.gao@...>; Justen, Jordan L <jordan.l.justen@...>; Laszlo Ersek <lersek@...>; Ard Biesheuvel <ard.biesheuvel@...>; Andrew Fish <afish@...>; Ni, Ray <ray.ni@...>
Subject: RE: [edk2-devel] [PATCH v6 00/14] Add the VariablePolicy feature

 

11 Days to go. I will single out an email every day…

 

Jian, today is your day.

How’s it going? Life good? Yeah, I know. Things are crazy here, too. Seattle is covered in smoke.

You know what would brighten things up, though? A nice “reviewed by”.

 

- Bret

 

From: Bret Barkelew via groups.io
Sent: Tuesday, September 8, 2020 3:20 PM
To: devel@edk2.groups.io; bret@...
Cc: Yao, Jiewen; Zhang, Chao B; Wang, Jian J; Wu, Hao A; liming.gao; Justen, Jordan L; Laszlo Ersek; Ard Biesheuvel; Andrew Fish; Ni, Ray; liming.gao
Subject: [EXTERNAL] Re: [edk2-devel] [PATCH v6 00/14] Add the VariablePolicy feature

 

Now that 2008 is labelled and everyone can take a breather… I still need reviews on the following patches (v7)…

Patch(es) 01, 02, 03,06,09,10,11,12,13,14

 

As such, the following email addresses may or may not be subscribed to CatFacts™ within the next 14 days if I get no responses:

Cc: Jian J Wang <jian.j.wang@...>
Cc: Hao A Wu <hao.a.wu@...>
Cc: Liming Gao <liming.gao@...>

Cc: Jordan Justen <jordan.l.justen@...>
Cc: Andrew Fish <afish@...>
Cc: Ray Ni <ray.ni@...>

Cc: Jiewen Yao <jiewen.yao@...>

Cc: Chao Zhang <chao.b.zhang@...>

 

May God have mercy on your inboxes.

 

- Bret

 

 

 


Re: [PATCH v7 00/14] Add the VariablePolicy feature

Bret Barkelew
 

Sounds good! Thanks! Will hold for at least this week. Still need some more RBs.

- Bret


From: devel@edk2.groups.io <devel@edk2.groups.io> on behalf of Dandan Bi via groups.io <dandan.bi@...>
Sent: Tuesday, September 15, 2020 8:44:01 AM
To: devel@edk2.groups.io <devel@edk2.groups.io>; bret@... <bret@...>
Cc: Yao, Jiewen <jiewen.yao@...>; Chao Zhang <chao.b.zhang@...>; Wang, Jian J <jian.j.wang@...>; Wu, Hao A <hao.a.wu@...>; liming.gao <liming.gao@...>; Justen, Jordan L <jordan.l.justen@...>; Laszlo Ersek <lersek@...>; Ard Biesheuvel <ard.biesheuvel@...>; Andrew Fish <afish@...>; Ni, Ray <ray.ni@...>
Subject: [EXTERNAL] Re: [edk2-devel] [PATCH v7 00/14] Add the VariablePolicy feature
 
Hi Bret,

The V7 version is OK from my side.  Reviewed-by: Dandan Bi <dandan.bi@...>
Please hold to see if any comments from other reviewers.


Hi Jiewen and Jian,

Do you have any comments?
 


Thanks,
Dandan
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Bret
> Barkelew
> Sent: Friday, August 28, 2020 1:51 PM
> To: devel@edk2.groups.io
> Cc: Yao, Jiewen <jiewen.yao@...>; Chao Zhang
> <chao.b.zhang@...>; Wang, Jian J <jian.j.wang@...>; Wu, Hao
> A <hao.a.wu@...>; Gao, Liming <liming.gao@...>; Justen,
> Jordan L <jordan.l.justen@...>; Laszlo Ersek <lersek@...>;
> Ard Biesheuvel <ard.biesheuvel@...>; Andrew Fish
> <afish@...>; Ni, Ray <ray.ni@...>
> Subject: [edk2-devel] [PATCH v7 00/14] Add the VariablePolicy feature
>
> The 14 patches in this series add the VariablePolicy feature to the core,
> deprecate Edk2VarLock (while adding a compatibility layer to reduce code
> churn), and integrate the VariablePolicy libraries and protocols into Variable
> Services.
>
> Since the integration requires multiple changes, including adding libraries, a
> protocol, an SMI communication handler, and VariableServices integration,
> the patches are broken up by individual library additions and then a final
> integration. Security-sensitive changes like bypassing Authenticated Variable
> enforcement are also broken out into individual patches so that attention can
> be called directly to them.
>
> Platform porting instructions are described in this wiki entry:
> https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FVariablePolicy-&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C28ce33648af54aa8e07f08d8598e59e2%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637357816016734689&amp;sdata=SwzfGHP86ZeenEaOIvbpU5mwrz9l25LTEuF0wPseGcY%3D&amp;reserved=0
> Protocol---Enhanced-Method-for-Managing-Variables#platform-porting
>
> Discussion of the feature can be found in multiple places throughout the last
> year on the RFC channel, staging branches, and in devel.
>
> Most recently, this subject was discussed in this thread:
> https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fedk2.groups.io%2Fg%2Fdevel%2Fmessage%2F53712&amp;data=02%7C01%7CBret.Barkelew%40microsoft.com%7C28ce33648af54aa8e07f08d8598e59e2%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637357816016734689&amp;sdata=F6Ywepo61wFPI5Cr14mHzJB6yCRyFA2JHevNGY8TwaQ%3D&amp;reserved=0
> (the code branches shared in that discussion are now out of date, but the
> whitepapers and discussion are relevant).
>
> Cc: Jiewen Yao <jiewen.yao@...>
> Cc: Chao Zhang <chao.b.zhang@...>
> Cc: Jian J Wang <jian.j.wang@...>
> Cc: Hao A Wu <hao.a.wu@...>
> Cc: Liming Gao <liming.gao@...>
> Cc: Jordan Justen <jordan.l.justen@...>
> Cc: Laszlo Ersek <lersek@...>
> Cc: Ard Biesheuvel <ard.biesheuvel@...>
> Cc: Andrew Fish <afish@...>
> Cc: Ray Ni <ray.ni@...>
> Cc: Bret Barkelew <brbarkel@...>
> Signed-off-by: Bret Barkelew <brbarkel@...>
>
> v7 changes:
> * Address comments from Dandan about security of the MM handler
> * Add readme
> * Fix bug around hex characters in BOOT####, etc
> * Add additional testing for hex characters
> * Add additional testing for authenticated variables
>
> v6 changes:
> * Fix an issue with uninitialized Status in InitVariablePolicyLib() and
> DeinitVariablePolicyLib()
> * Fix GCC building in shell-based functional test
> * Rebase on latest origin/master
>
> v5 changes:
> * Fix the CONST mismatch in VariablePolicy.h and VariablePolicySmmDxe.c
> * Fix EFIAPI mismatches in the functional unittest
> * Rebase on latest origin/master
>
> v4 changes:
> * Remove Optional PcdAllowVariablePolicyEnforcementDisable PCD from
> platforms
> * Rebase on master
> * Migrate to new MmCommunicate2 protocol
> * Fix an oversight in the default return value for
> InitMmCommonCommBuffer
> * Fix in VariablePolicyLib to allow ExtraInitRuntimeDxe to consume variables
>
> V3 changes:
> * Address all non-unittest issues with ECC
> * Make additional style changes
> * Include section name in hunk headers in "ini-style" files
> * Remove requirement for the EdkiiPiSmmCommunicationsRegionTable
> driver
>   (now allocates its own buffer)
> * Change names from VARIABLE_POLICY_PROTOCOL and
> gVariablePolicyProtocolGuid
>   to EDKII_VARIABLE_POLICY_PROTOCOL and
> gEdkiiVariablePolicyProtocolGuid
> * Fix GCC warning about initializing externs
> * Add UNI strings for new PCD
> * Add patches for ArmVirtPkg, OvmfXen, and UefiPayloadPkg
> * Reorder patches according to Liming's feedback about adding to platforms
>   before changing variable driver
>
> V2 changes:
> * Fixed implementation for RuntimeDxe
> * Add PCD to block DisableVariablePolicy
> * Fix the DumpVariablePolicy pagination in SMM
>
>
> Bret Barkelew (14):
>   MdeModulePkg: Define the VariablePolicy protocol interface
>   MdeModulePkg: Define the VariablePolicyLib
>   MdeModulePkg: Define the VariablePolicyHelperLib
>   MdeModulePkg: Define the VarCheckPolicyLib and SMM interface
>   OvmfPkg: Add VariablePolicy engine to OvmfPkg platform
>   EmulatorPkg: Add VariablePolicy engine to EmulatorPkg platform
>   ArmVirtPkg: Add VariablePolicy engine to ArmVirtPkg platform
>   UefiPayloadPkg: Add VariablePolicy engine to UefiPayloadPkg platform
>   MdeModulePkg: Connect VariablePolicy business logic to
>     VariableServices
>   MdeModulePkg: Allow VariablePolicy state to delete protected variables
>   SecurityPkg: Allow VariablePolicy state to delete authenticated
>     variables
>   MdeModulePkg: Change TCG MOR variables to use VariablePolicy
>   MdeModulePkg: Drop VarLock from RuntimeDxe variable driver
>   MdeModulePkg: Add a shell-based functional test for VariablePolicy
>
>  MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c
> |  345 +++
>  MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.c
> |  396 ++++
>  MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitNull.c
> |   46 +
>
> MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitRuntimeDx
> e.c               |   85 +
>  MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
> |  830 +++++++
>
> MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/VariablePo
> licyUnitTest.c   | 2452 ++++++++++++++++++++
>
> MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFu
> ncTestApp.c        | 2226 ++++++++++++++++++
>  MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockDxe.c
> |   52 +-
>  MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c
> |   60 +-
>  MdeModulePkg/Universal/Variable/RuntimeDxe/VarCheck.c
> |   49 +-
>  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c
> |   53 +
>
> MdeModulePkg/Universal/Variable/RuntimeDxe/VariableLockRequstToLock
> .c                    |   71 +
>  MdeModulePkg/Universal/Variable/RuntimeDxe/VariablePolicySmmDxe.c
> |  642 +++++
>
> MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.
> c                       |   14 +
>  SecurityPkg/Library/AuthVariableLib/AuthService.c                                        |   22
> +-
>  ArmVirtPkg/ArmVirt.dsc.inc                                                               |    4 +
>  EmulatorPkg/EmulatorPkg.dsc                                                              |    3 +
>  MdeModulePkg/Include/Guid/VarCheckPolicyMmi.h                                            |
> 54 +
>  MdeModulePkg/Include/Library/VariablePolicyHelperLib.h
> |  164 ++
>  MdeModulePkg/Include/Library/VariablePolicyLib.h                                         |
> 207 ++
>  MdeModulePkg/Include/Protocol/VariablePolicy.h                                           |
> 157 ++
>  MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.inf
> |   42 +
>  MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.uni
> |   12 +
>  MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
> |   35 +
>  MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.uni
> |   12 +
>  MdeModulePkg/Library/VariablePolicyLib/ReadMe.md                                         |
> 410 ++++
>  MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
> |   49 +
>  MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.uni
> |   12 +
>  MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf
> |   51 +
>
> MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/VariablePo
> licyUnitTest.inf |   45 +
>  MdeModulePkg/MdeModulePkg.ci.yaml                                                        |    8 +-
>  MdeModulePkg/MdeModulePkg.dec                                                            |   26 +-
>  MdeModulePkg/MdeModulePkg.dsc                                                            |    9 +
>  MdeModulePkg/MdeModulePkg.uni                                                            |    7 +
>  MdeModulePkg/Test/MdeModulePkgHostTest.dsc                                               |
> 11 +
>  MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Readme.md
> |   55 +
>
> MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFu
> ncTestApp.inf      |   47 +
>
> MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyTe
> stAuthVar.h        |  128 +
>  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
> |    5 +
>  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf
> |    4 +
>
> MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.i
> nf                     |   11 +
>
> MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
> |    4 +
>  OvmfPkg/OvmfPkgIa32.dsc                                                                  |    5 +
>  OvmfPkg/OvmfPkgIa32X64.dsc                                                               |    5 +
>  OvmfPkg/OvmfPkgX64.dsc                                                                   |    5 +
>  OvmfPkg/OvmfXen.dsc                                                                      |    4 +
>  SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf                                  |
> 2 +
>  UefiPayloadPkg/UefiPayloadPkgIa32.dsc                                                    |    4 +
>  UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc                                                 |    4 +
>  49 files changed, 8865 insertions(+), 79 deletions(-)  create mode 100644
> MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c
>  create mode 100644
> MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.c
>  create mode 100644
> MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitNull.c
>  create mode 100644
> MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitRuntimeDx
> e.c
>  create mode 100644
> MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
>  create mode 100644
> MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/VariablePo
> licyUnitTest.c
>  create mode 100644
> MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFu
> ncTestApp.c
>  create mode 100644
> MdeModulePkg/Universal/Variable/RuntimeDxe/VariableLockRequstToLock
> .c
>  create mode 100644
> MdeModulePkg/Universal/Variable/RuntimeDxe/VariablePolicySmmDxe.c
>  create mode 100644 MdeModulePkg/Include/Guid/VarCheckPolicyMmi.h
>  create mode 100644
> MdeModulePkg/Include/Library/VariablePolicyHelperLib.h
>  create mode 100644 MdeModulePkg/Include/Library/VariablePolicyLib.h
>  create mode 100644 MdeModulePkg/Include/Protocol/VariablePolicy.h
>  create mode 100644
> MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.inf
>  create mode 100644
> MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.uni
>  create mode 100644
> MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
>  create mode 100644
> MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.uni
>  create mode 100644 MdeModulePkg/Library/VariablePolicyLib/ReadMe.md
>  create mode 100644
> MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
>  create mode 100644
> MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.uni
>  create mode 100644
> MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf
>  create mode 100644
> MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/VariablePo
> licyUnitTest.inf
>  create mode 100644
> MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Readme.md
>  create mode 100644
> MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFu
> ncTestApp.inf
>  create mode 100644
> MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyTe
> stAuthVar.h
>
> --
> 2.28.0.windows.1
>
>
>





[PATCH v12 1/1] ShellPkg/DynamicCommand: add HttpDynamicCommand

Vladimir Olovyannikov
 

Introduce an http client utilizing EDK2 HTTP protocol, to
allow fast image downloading from http/https servers.
HTTP download speed is usually faster than tftp.
The client is based on the same approach as tftp dynamic command, and
uses the same UEFI Shell command line parameters. This makes it easy
integrating http into existing UEFI Shell scripts.
Note that to enable HTTP download, feature Pcd
gEfiNetworkPkgTokenSpaceGuid.PcdAllowHttpConnections must
be set to TRUE.
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2860

Signed-off-by: Vladimir Olovyannikov <vladimir.olovyannikov@broadcom.com>
Cc: Samer El-Haj-Mahmoud <Samer.El-Haj-Mahmoud@arm.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Zhichao Gao <zhichao.gao@intel.com>
Cc: Maciej Rabeda <maciej.rabeda@linux.intel.com>
Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Nd <nd@arm.com>
---
ShellPkg/ShellPkg.dec | 1 +
ShellPkg/ShellPkg.dsc | 5 +
.../HttpDynamicCommand/HttpApp.inf | 58 +
.../HttpDynamicCommand/HttpDynamicCommand.inf | 63 +
.../DynamicCommand/HttpDynamicCommand/Http.h | 90 +
ShellPkg/Include/Guid/ShellLibHiiGuid.h | 5 +
.../DynamicCommand/HttpDynamicCommand/Http.c | 1843 +++++++++++++++++
.../HttpDynamicCommand/HttpApp.c | 61 +
.../HttpDynamicCommand/HttpDynamicCommand.c | 137 ++
.../HttpDynamicCommand/Http.uni | 117 ++
10 files changed, 2380 insertions(+)
create mode 100644 ShellPkg/DynamicCommand/HttpDynamicCommand/HttpApp.inf
create mode 100644 ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.inf
create mode 100644 ShellPkg/DynamicCommand/HttpDynamicCommand/Http.h
create mode 100644 ShellPkg/DynamicCommand/HttpDynamicCommand/Http.c
create mode 100644 ShellPkg/DynamicCommand/HttpDynamicCommand/HttpApp.c
create mode 100644 ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.c
create mode 100644 ShellPkg/DynamicCommand/HttpDynamicCommand/Http.uni

diff --git a/ShellPkg/ShellPkg.dec b/ShellPkg/ShellPkg.dec
index d0843d338126..7b2d1230bd2c 100644
--- a/ShellPkg/ShellPkg.dec
+++ b/ShellPkg/ShellPkg.dec
@@ -53,6 +53,7 @@ [Guids]
gShellNetwork1HiiGuid = {0xf3d301bb, 0xf4a5, 0x45a8, {0xb0, 0xb7, 0xfa, 0x99, 0x9c, 0x62, 0x37, 0xae}}
gShellNetwork2HiiGuid = {0x174b2b5, 0xf505, 0x4b12, {0xaa, 0x60, 0x59, 0xdf, 0xf8, 0xd6, 0xea, 0x37}}
gShellTftpHiiGuid = {0x738a9314, 0x82c1, 0x4592, {0x8f, 0xf7, 0xc1, 0xbd, 0xf1, 0xb2, 0x0e, 0xd4}}
+ gShellHttpHiiGuid = {0x390f84b3, 0x221c, 0x4d9e, {0xb5, 0x06, 0x6d, 0xb9, 0x42, 0x3e, 0x0a, 0x7e}}
gShellBcfgHiiGuid = {0x5f5f605d, 0x1583, 0x4a2d, {0xa6, 0xb2, 0xeb, 0x12, 0xda, 0xb4, 0xa2, 0xb6}}
gShellAcpiViewHiiGuid = {0xda8ccdf4, 0xed8f, 0x4ffc, {0xb5, 0xef, 0x2e, 0xf5, 0x5e, 0x24, 0x93, 0x2a}}
# FILE_GUID as defined in ShellPkg/Application/Shell/Shell.inf
diff --git a/ShellPkg/ShellPkg.dsc b/ShellPkg/ShellPkg.dsc
index 86e9f1e0040d..c42bc9464a0f 100644
--- a/ShellPkg/ShellPkg.dsc
+++ b/ShellPkg/ShellPkg.dsc
@@ -139,6 +139,11 @@ [Components]
gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
}
ShellPkg/DynamicCommand/TftpDynamicCommand/TftpApp.inf
+ ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.inf {
+ <PcdsFixedAtBuild>
+ gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+ }
+ ShellPkg/DynamicCommand/HttpDynamicCommand/HttpApp.inf
ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf {
<PcdsFixedAtBuild>
gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
diff --git a/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpApp.inf b/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpApp.inf
new file mode 100644
index 000000000000..d08d47fb37d5
--- /dev/null
+++ b/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpApp.inf
@@ -0,0 +1,58 @@
+## @file
+# Provides Shell 'http' standalone application.
+#
+# Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved. <BR>
+# Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
+# Copyright (c) 2020, Broadcom. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = http
+ FILE_GUID = 56B00FB7-91D2-869B-CE5C-26CD1A89C73C
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = HttpAppInitialize
+#
+# This flag specifies whether HII resource section is generated into PE image.
+#
+ UEFI_HII_RESOURCE_SECTION = TRUE
+
+[Sources.common]
+ Http.c
+ HttpApp.c
+ Http.h
+ Http.uni
+
+[Packages]
+ EmbeddedPkg/EmbeddedPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+ NetworkPkg/NetworkPkg.dec
+ ShellPkg/ShellPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ FileHandleLib
+ HiiLib
+ HttpLib
+ MemoryAllocationLib
+ NetLib
+ ShellLib
+ UefiApplicationEntryPoint
+ UefiBootServicesTableLib
+ UefiHiiServicesLib
+ UefiLib
+ UefiRuntimeServicesTableLib
+
+[Protocols]
+ gEfiHiiPackageListProtocolGuid ## CONSUMES
+ gEfiHttpProtocolGuid ## CONSUMES
+ gEfiHttpServiceBindingProtocolGuid ## CONSUMES
+ gEfiManagedNetworkServiceBindingProtocolGuid ## CONSUMES
diff --git a/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.inf b/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.inf
new file mode 100644
index 000000000000..5d46ee2384d5
--- /dev/null
+++ b/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.inf
@@ -0,0 +1,63 @@
+## @file
+# Provides Shell 'http' dynamic command.
+#
+# Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved. <BR>
+# Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
+# Copyright (c) 2020, Broadcom. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = httpDynamicCommand
+ FILE_GUID = 19618BCE-55AE-09C6-37E9-4CE04084C7A1
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = HttpCommandInitialize
+ UNLOAD_IMAGE = HttpUnload
+#
+# This flag specifies whether HII resource section is generated into PE image.
+#
+ UEFI_HII_RESOURCE_SECTION = TRUE
+
+[Sources.common]
+ Http.c
+ HttpDynamicCommand.c
+ Http.h
+ Http.uni
+
+[Packages]
+ EmbeddedPkg/EmbeddedPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ NetworkPkg/NetworkPkg.dec
+ ShellPkg/ShellPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ FileHandleLib
+ HiiLib
+ HttpLib
+ MemoryAllocationLib
+ NetLib
+ ShellLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiHiiServicesLib
+ UefiLib
+ UefiRuntimeServicesTableLib
+
+[Protocols]
+ gEfiHiiPackageListProtocolGuid ## CONSUMES
+ gEfiHttpProtocolGuid ## CONSUMES
+ gEfiHttpServiceBindingProtocolGuid ## CONSUMES
+ gEfiManagedNetworkServiceBindingProtocolGuid ## CONSUMES
+ gEfiShellDynamicCommandProtocolGuid ## PRODUCES
+
+[DEPEX]
+ TRUE
diff --git a/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.h b/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.h
new file mode 100644
index 000000000000..c53479b823e7
--- /dev/null
+++ b/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.h
@@ -0,0 +1,90 @@
+/** @file
+ Header file for 'http' command functions.
+
+ Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved. <BR>
+ Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2020, Broadcom. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _HTTP_H_
+#define _HTTP_H_
+
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HiiLib.h>
+#include <Library/HttpLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/NetLib.h>
+#include <Library/PrintLib.h>
+#include <Library/ShellLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiHiiServicesLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+#include <Protocol/HiiPackageList.h>
+#include <Protocol/HttpUtilities.h>
+#include <Protocol/ServiceBinding.h>
+
+#define HTTP_APP_NAME L"http"
+
+#define REQ_OK 0
+#define REQ_NEED_REPEAT 1
+
+// Download Flags
+#define DL_FLAG_TIME BIT0 // Show elapsed time.
+#define DL_FLAG_KEEP_BAD BIT1 // Keep files even if download failed.
+
+extern EFI_HII_HANDLE mHttpHiiHandle;
+
+typedef struct {
+ UINTN ContentDownloaded;
+ UINTN ContentLength;
+ UINTN LastReportedNbOfBytes;
+ UINTN BufferSize;
+ UINTN Status;
+ UINTN Flags;
+ UINT8 *Buffer;
+ CHAR16 *ServerAddrAndProto;
+ CHAR16 *URI;
+ EFI_HTTP_TOKEN ResponseToken;
+ EFI_HTTP_TOKEN RequestToken;
+ EFI_HTTP_PROTOCOL *Http;
+ EFI_HTTP_CONFIG_DATA HttpConfigData;
+} HTTP_DOWNLOAD_CONTEXT;
+
+/**
+ Function for 'http' command.
+
+ @param[in] ImageHandle The image handle.
+ @param[in] SystemTable The system table.
+
+ @retval SHELL_SUCCESS Command completed successfully.
+ @retval SHELL_INVALID_PARAMETER Command usage error.
+ @retval SHELL_ABORTED The user aborts the operation.
+ @retval value Unknown error.
+**/
+SHELL_STATUS
+RunHttp (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+/**
+ Retrive HII package list from ImageHandle and publish to HII database.
+
+ @param ImageHandle The image handle of the process.
+
+ @return HII handle.
+**/
+EFI_HII_HANDLE
+InitializeHiiPackage (
+ EFI_HANDLE ImageHandle
+ );
+#endif // _HTTP_H_
diff --git a/ShellPkg/Include/Guid/ShellLibHiiGuid.h b/ShellPkg/Include/Guid/ShellLibHiiGuid.h
index 5da9128333a4..6e328b460d8c 100644
--- a/ShellPkg/Include/Guid/ShellLibHiiGuid.h
+++ b/ShellPkg/Include/Guid/ShellLibHiiGuid.h
@@ -59,6 +59,10 @@
0x738a9314, 0x82c1, 0x4592, { 0x8f, 0xf7, 0xc1, 0xbd, 0xf1, 0xb2, 0x0e, 0xd4 } \
}

+#define SHELL_HTTP_HII_GUID \
+ { \
+ 0x390f84b3, 0x221c, 0x4d9e, { 0xb5, 0x06, 0x6d, 0xb9, 0x42, 0x3e, 0x0a, 0x7e } \
+ }

#define SHELL_BCFG_HII_GUID \
{ \
@@ -75,6 +79,7 @@ extern EFI_GUID gShellLevel3HiiGuid;
extern EFI_GUID gShellNetwork1HiiGuid;
extern EFI_GUID gShellNetwork2HiiGuid;
extern EFI_GUID gShellTftpHiiGuid;
+extern EFI_GUID gShellHttpHiiGuid;
extern EFI_GUID gShellBcfgHiiGuid;

#endif
diff --git a/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.c b/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.c
new file mode 100644
index 000000000000..3f11c1cd84c3
--- /dev/null
+++ b/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.c
@@ -0,0 +1,1843 @@
+/** @file
+ The implementation for the 'http' Shell command.
+
+ Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved. <BR>
+ (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
+ Copyright (c) 2020, Broadcom. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "Http.h"
+
+#define IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH 32
+
+/*
+ Constant strings and definitions related to the message
+ indicating the amount of progress in the dowloading of a HTTP file.
+*/
+
+// Number of steps in the progression slider
+#define HTTP_PROGRESS_SLIDER_STEPS \
+ ((sizeof (HTTP_PROGR_FRAME) / sizeof (CHAR16)) - 3)
+
+// Size in number of characters plus one (final zero) of the message to
+// indicate the progress of an HTTP download. The format is "[(progress slider:
+// 40 characters)] (nb of KBytes downloaded so far: 7 characters) Kb". There
+// are thus the number of characters in HTTP_PROGR_FRAME[] plus 11 characters
+// (2 // spaces, "Kb" and seven characters for the number of KBytes).
+#define HTTP_PROGRESS_MESSAGE_SIZE \
+ ((sizeof (HTTP_PROGR_FRAME) / sizeof (CHAR16)) + 12)
+
+//
+// Buffer size. Note that larger buffer does not mean better speed!
+//
+#define DEFAULT_BUF_SIZE SIZE_32KB
+#define MAX_BUF_SIZE SIZE_4MB
+
+#define MIN_PARAM_COUNT 2
+#define MAX_PARAM_COUNT 4
+#define NEED_REDIRECTION(Code) \
+ (((Code >= HTTP_STATUS_300_MULTIPLE_CHOICES) \
+ && (Code <= HTTP_STATUS_307_TEMPORARY_REDIRECT)) \
+ || (Code == HTTP_STATUS_308_PERMANENT_REDIRECT))
+
+#define CLOSE_HTTP_HANDLE(ControllerHandle,HttpChildHandle) \
+ do { \
+ if (HttpChildHandle) { \
+ CloseProtocolAndDestroyServiceChild ( \
+ ControllerHandle, \
+ &gEfiHttpServiceBindingProtocolGuid, \
+ &gEfiHttpProtocolGuid, \
+ HttpChildHandle \
+ ); \
+ HttpChildHandle = NULL; \
+ } \
+ } while (0)
+
+typedef enum {
+ HDR_HOST,
+ HDR_CONN,
+ HDR_AGENT,
+ HDR_MAX
+} HDR_TYPE;
+
+#define USER_AGENT_HDR "Mozilla/5.0 (EDK2; Linux) Gecko/20100101 Firefox/79.0"
+
+#define TIMER_MAX_TIMEOUT_S 10
+
+// File name to use when URI ends with "/"
+#define DEFAULT_HTML_FILE L"index.html"
+#define DEFAULT_HTTP_PROTO L"http"
+
+// String to delete the HTTP progress message to be able to update it :
+// (HTTP_PROGRESS_MESSAGE_SIZE-1) '\b'
+#define HTTP_PROGRESS_DEL \
+ L"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\
+\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
+
+#define HTTP_KB L"\b\b\b\b\b\b\b\b\b\b"
+// Frame for the progression slider
+#define HTTP_PROGR_FRAME L"[ ]"
+
+// Improve readability by using these macros
+#define PRINT_HII(token,...) \
+ ShellPrintHiiEx (\
+ -1, -1, NULL, token, mHttpHiiHandle, __VA_ARGS__)
+
+#define PRINT_HII_APP(token,value) \
+ PRINT_HII (token, HTTP_APP_NAME, value)
+
+//
+// TimeBaseLib.h constants.
+// TODO: remove once the library gets fixed.
+//
+
+// Define EPOCH (1970-JANUARY-01) in the Julian Date representation
+#define EPOCH_JULIAN_DATE 2440588
+
+// Seconds per unit
+#define SEC_PER_MIN ((UINTN) 60)
+#define SEC_PER_HOUR ((UINTN) 3600)
+#define SEC_PER_DAY ((UINTN) 86400)
+
+
+// String descriptions for server errors
+STATIC CONST CHAR16 *ErrStatusDesc[] =
+{
+ L"400 Bad Request",
+ L"401 Unauthorized",
+ L"402 Payment required",
+ L"403 Forbidden",
+ L"404 Not Found",
+ L"405 Method not allowed",
+ L"406 Not acceptable",
+ L"407 Proxy authentication required",
+ L"408 Request time out",
+ L"409 Conflict",
+ L"410 Gone",
+ L"411 Length required",
+ L"412 Precondition failed",
+ L"413 Request entity too large",
+ L"414 Request URI to large",
+ L"415 Unsupported media type",
+ L"416 Requested range not satisfied",
+ L"417 Expectation failed",
+ L"500 Internal server error",
+ L"501 Not implemented",
+ L"502 Bad gateway",
+ L"503 Service unavailable",
+ L"504 Gateway timeout",
+ L"505 HTTP version not supported"
+};
+
+STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
+ {L"-i", TypeValue},
+ {L"-k", TypeFlag},
+ {L"-l", TypeValue},
+ {L"-m", TypeFlag},
+ {L"-s", TypeValue},
+ {L"-t", TypeValue},
+ {NULL , TypeMax}
+};
+
+// Local File Handle
+STATIC SHELL_FILE_HANDLE mFileHandle = NULL;
+
+// Path of the local file, Unicode encoded
+STATIC CONST CHAR16 *mLocalFilePath;
+
+STATIC BOOLEAN gRequestCallbackComplete = FALSE;
+STATIC BOOLEAN gResponseCallbackComplete = FALSE;
+
+STATIC BOOLEAN gHttpError;
+
+EFI_HII_HANDLE mHttpHiiHandle;
+
+// Functions declarations
+/**
+ Check and convert the UINT16 option values of the 'http' command
+
+ @param[in] ValueStr Value as an Unicode encoded string
+ @param[out] Value UINT16 value
+
+ @return TRUE The value was returned.
+ @return FALSE A parsing error occured.
+**/
+STATIC
+BOOLEAN
+StringToUint16 (
+ IN CONST CHAR16 *ValueStr,
+ OUT UINT16 *Value
+ );
+
+/**
+ Get the name of the NIC.
+
+ @param[in] ControllerHandle The network physical device handle.
+ @param[in] NicNumber The network physical device number.
+ @param[out] NicName Address where to store the NIC name.
+ The memory area has to be at least
+ IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH
+ double byte wide.
+
+ @return EFI_SUCCESS The name of the NIC was returned.
+ @return Others The creation of the child for the Managed
+ Network Service failed or the opening of
+ the Managed Network Protocol failed or
+ the operational parameters for the
+ Managed Network Protocol could not be
+ read.
+**/
+STATIC
+EFI_STATUS
+GetNicName (
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NicNumber,
+ OUT CHAR16 *NicName
+ );
+
+/**
+ Create a child for the service identified by its service binding protocol GUID
+ and get from the child the interface of the protocol identified by its GUID.
+
+ @param[in] ControllerHandle Controller handle.
+ @param[in] ServiceBindingProtocolGuid Service binding protocol GUID of the
+ service to be created.
+ @param[in] ProtocolGuid GUID of the protocol to be open.
+ @param[out] ChildHandle Address where the handler of the
+ created child is returned. NULL is
+ returned in case of error.
+ @param[out] Interface Address where a pointer to the
+ protocol interface is returned in
+ case of success.
+
+ @return EFI_SUCCESS The child was created and the protocol opened.
+ @return Others Either the creation of the child or the opening
+ of the protocol failed.
+**/
+STATIC
+EFI_STATUS
+CreateServiceChildAndOpenProtocol (
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_GUID *ServiceBindingProtocolGuid,
+ IN EFI_GUID *ProtocolGuid,
+ OUT EFI_HANDLE *ChildHandle,
+ OUT VOID **Interface
+ );
+
+/**
+ Close the protocol identified by its GUID on the child handle of the service
+ identified by its service binding protocol GUID, then destroy the child
+ handle.
+
+ @param[in] ControllerHandle Controller handle.
+ @param[in] ServiceBindingProtocolGuid Service binding protocol GUID of the
+ service to be destroyed.
+ @param[in] ProtocolGuid GUID of the protocol to be closed.
+ @param[in] ChildHandle Handle of the child to be destroyed.
+
+**/
+STATIC
+VOID
+CloseProtocolAndDestroyServiceChild (
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_GUID *ServiceBindingProtocolGuid,
+ IN EFI_GUID *ProtocolGuid,
+ IN EFI_HANDLE ChildHandle
+ );
+
+/**
+ Worker function that download the data of a file from an HTTP server given
+ the path of the file and its size.
+
+ @param[in] Context A pointer to the download context.
+
+ @retval EFI_SUCCESS The file was downloaded.
+ @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
+ @retval Others The downloading of the file
+ from the server failed.
+
+**/
+STATIC
+EFI_STATUS
+DownloadFile (
+ IN HTTP_DOWNLOAD_CONTEXT *Context,
+ IN EFI_HANDLE ControllerHandle,
+ IN CHAR16 *NicName
+ );
+
+/**
+ Cleans off leading and trailing spaces and tabs.
+
+ @param[in] String pointer to the string to trim them off.
+**/
+STATIC
+EFI_STATUS
+TrimSpaces (
+ IN CHAR16 *String
+ )
+{
+ CHAR16 *Str;
+ UINTN Len;
+
+ ASSERT (String != NULL);
+
+ if (!String) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Str = String;
+
+ //
+ // Remove any whitespace at the beginning of the Str.
+ //
+ while (*Str == L' ' || *Str == L'\t') {
+ Str++;
+ }
+
+ //
+ // Remove any whitespace at the end of the Str.
+ //
+ do {
+ Len = StrLen (Str);
+ if (!Len || (Str[Len - 1] != L' ' && Str[Len - 1] != '\t')) {
+ break;
+ }
+
+ Str[Len - 1] = CHAR_NULL;
+ } while (Len);
+
+ CopyMem (String, Str, StrSize (Str));
+
+ return EFI_SUCCESS;
+}
+
+
+/*
+ * Callbacks for request and response.
+ * We just acknowledge that operation has completed here.
+ */
+STATIC
+VOID
+EFIAPI
+RequestCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ gRequestCallbackComplete = TRUE;
+}
+
+STATIC
+VOID
+EFIAPI
+ResponseCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ gResponseCallbackComplete = TRUE;
+}
+
+//
+// Set of functions from TimeBaseLib.
+// TODO: remove once TimeBaseLib gets fixed, and enabled for ShellPkg.
+//
+
+/**
+ Calculate Epoch days
+ **/
+STATIC
+UINTN
+EfiGetEpochDays (
+ IN EFI_TIME *Time
+ )
+{
+ UINTN a;
+ UINTN y;
+ UINTN m;
+ UINTN JulianDate; // Absolute Julian Date representation of the supplied Time
+ UINTN EpochDays; // Number of days elapsed since EPOCH_JULIAN_DAY
+
+ a = (14 - Time->Month) / 12 ;
+ y = Time->Year + 4800 - a;
+ m = Time->Month + (12 * a) - 3;
+
+ JulianDate = Time->Day + ((153 * m + 2) / 5) + (365 * y) + (y / 4) -
+ (y / 100) + (y / 400) - 32045;
+
+ ASSERT (JulianDate >= EPOCH_JULIAN_DATE);
+ EpochDays = JulianDate - EPOCH_JULIAN_DATE;
+
+ return EpochDays;
+}
+
+/**
+ Converts EFI_TIME to Epoch seconds
+ (elapsed since 1970 JANUARY 01, 00:00:00 UTC)
+ **/
+STATIC
+UINTN
+EFIAPI
+EfiTimeToEpoch (
+ IN EFI_TIME *Time
+ )
+{
+ UINTN EpochDays; // Number of days elapsed since EPOCH_JULIAN_DAY
+ UINTN EpochSeconds;
+
+ EpochDays = EfiGetEpochDays (Time);
+
+ EpochSeconds = (EpochDays * SEC_PER_DAY) +
+ ((UINTN)Time->Hour * SEC_PER_HOUR) +
+ (Time->Minute * SEC_PER_MIN) + Time->Second;
+
+ return EpochSeconds;
+}
+
+/**
+ Function for 'http' command.
+
+ @param[in] ImageHandle Handle to the Image (NULL if Internal).
+ @param[in] SystemTable Pointer to the System Table (NULL if Internal).
+
+ @return SHELL_SUCCESS The 'http' command completed successfully.
+ @return SHELL_ABORTED The Shell Library initialization failed.
+ @return SHELL_INVALID_PARAMETER At least one of the command's arguments is
+ not valid.
+ @return SHELL_OUT_OF_RESOURCES A memory allocation failed.
+ @return SHELL_NOT_FOUND Network Interface Card not found.
+ @return SHELL_UNSUPPORTED Command was valid, but the server returned
+ a status code indicating some error.
+ Examine the file requested for error body.
+
+**/
+SHELL_STATUS
+RunHttp (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ LIST_ENTRY *CheckPackage;
+ UINTN ParamCount;
+ UINTN HandleCount;
+ UINTN NicNumber;
+ UINTN InitialSize;
+ UINTN ParamOffset;
+ UINTN StartSize;
+ CHAR16 *ProblemParam;
+ CHAR16 NicName[IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH];
+ CHAR16 *Walker1;
+ CHAR16 *VStr;
+ CONST CHAR16 *UserNicName;
+ CONST CHAR16 *ValueStr;
+ CONST CHAR16 *RemoteFilePath;
+ CONST CHAR16 *Walker;
+ EFI_HTTPv4_ACCESS_POINT IPv4Node;
+ EFI_HANDLE *Handles;
+ EFI_HANDLE ControllerHandle;
+ HTTP_DOWNLOAD_CONTEXT Context;
+ BOOLEAN NicFound;
+
+ ProblemParam = NULL;
+ RemoteFilePath = NULL;
+ NicFound = FALSE;
+ Handles = NULL;
+
+ //
+ // Initialize the Shell library (we must be in non-auto-init...)
+ //
+ ParamOffset = 0;
+ gHttpError = FALSE;
+
+ Status = ShellInitialize ();
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return SHELL_ABORTED;
+ }
+
+ ZeroMem (&Context, sizeof (Context));
+
+ //
+ // Parse the command line.
+ //
+ Status = ShellCommandLineParse (
+ ParamList,
+ &CheckPackage,
+ &ProblemParam,
+ TRUE
+ );
+ if (EFI_ERROR (Status)) {
+ if ((Status == EFI_VOLUME_CORRUPTED)
+ && (ProblemParam != NULL))
+ {
+ PRINT_HII_APP (STRING_TOKEN (STR_GEN_PROBLEM), ProblemParam);
+ SHELL_FREE_NON_NULL (ProblemParam);
+ } else {
+ ASSERT (FALSE);
+ }
+
+ goto Error;
+ }
+
+ //
+ // Check the number of parameters
+ //
+ Status = EFI_INVALID_PARAMETER;
+
+ ParamCount = ShellCommandLineGetCount (CheckPackage);
+ if (ParamCount > MAX_PARAM_COUNT) {
+ PRINT_HII_APP (STRING_TOKEN (STR_GEN_TOO_MANY), NULL);
+ goto Error;
+ }
+
+ if (ParamCount < MIN_PARAM_COUNT) {
+ PRINT_HII_APP (STRING_TOKEN (STR_GEN_TOO_FEW), NULL);
+ goto Error;
+ }
+
+ ZeroMem (&Context.HttpConfigData, sizeof (Context.HttpConfigData));
+ ZeroMem (&IPv4Node, sizeof (IPv4Node));
+ IPv4Node.UseDefaultAddress = TRUE;
+
+ Context.HttpConfigData.HttpVersion = HttpVersion11;
+ Context.HttpConfigData.AccessPoint.IPv4Node = &IPv4Node;
+
+ //
+ // Get the host address (not necessarily IPv4 format)
+ //
+ ValueStr = ShellCommandLineGetRawValue (CheckPackage, 1);
+ if (!ValueStr) {
+ PRINT_HII_APP (STRING_TOKEN (STR_GEN_PARAM_INV), ValueStr);
+ goto Error;
+ } else {
+ StartSize = 0;
+ TrimSpaces ((CHAR16 *)ValueStr);
+ if (!StrStr (ValueStr, L"://")) {
+ Context.ServerAddrAndProto = StrnCatGrow (
+ &Context.ServerAddrAndProto,
+ &StartSize,
+ DEFAULT_HTTP_PROTO,
+ StrLen (DEFAULT_HTTP_PROTO)
+ );
+ Context.ServerAddrAndProto = StrnCatGrow (
+ &Context.ServerAddrAndProto,
+ &StartSize,
+ L"://",
+ StrLen (L"://")
+ );
+ VStr = (CHAR16 *)ValueStr;
+ } else {
+ VStr = StrStr (ValueStr, L"://") + StrLen (L"://");
+ }
+
+ for (Walker1 = VStr; *Walker1; Walker1++) {
+ if (*Walker1 == L'/') {
+ break;
+ }
+ }
+
+ if (*Walker1 == L'/') {
+ ParamOffset = 1;
+ RemoteFilePath = Walker1;
+ }
+
+ Context.ServerAddrAndProto = StrnCatGrow (
+ &Context.ServerAddrAndProto,
+ &StartSize,
+ ValueStr,
+ StrLen (ValueStr) - StrLen (Walker1)
+ );
+ if (!Context.ServerAddrAndProto) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+ }
+
+ if (!RemoteFilePath) {
+ RemoteFilePath = ShellCommandLineGetRawValue (CheckPackage, 2);
+ if (!RemoteFilePath) {
+ // If no path given, assume just "/"
+ RemoteFilePath = L"/";
+ }
+ }
+
+ TrimSpaces ((CHAR16 *)RemoteFilePath);
+
+ if (ParamCount == MAX_PARAM_COUNT - ParamOffset) {
+ mLocalFilePath = ShellCommandLineGetRawValue (
+ CheckPackage,
+ MAX_PARAM_COUNT - 1 - ParamOffset
+ );
+ } else {
+ Walker = RemoteFilePath + StrLen (RemoteFilePath);
+ while ((--Walker) >= RemoteFilePath) {
+ if ((*Walker == L'\\') ||
+ (*Walker == L'/' ) ) {
+ break;
+ }
+ }
+
+ mLocalFilePath = Walker + 1;
+ }
+
+ if (!StrLen (mLocalFilePath)) {
+ mLocalFilePath = DEFAULT_HTML_FILE;
+ }
+
+ InitialSize = 0;
+ Context.URI = StrnCatGrow (
+ &Context.URI,
+ &InitialSize,
+ RemoteFilePath,
+ StrLen (RemoteFilePath)
+ );
+ if (!Context.URI) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+
+ //
+ // Get the name of the Network Interface Card to be used if any.
+ //
+ UserNicName = ShellCommandLineGetValue (CheckPackage, L"-i");
+
+ ValueStr = ShellCommandLineGetValue (CheckPackage, L"-l");
+ if ((ValueStr != NULL)
+ && (!StringToUint16 (
+ ValueStr,
+ &Context.HttpConfigData.AccessPoint.IPv4Node->LocalPort
+ )
+ ))
+ {
+ goto Error;
+ }
+
+ Context.BufferSize = DEFAULT_BUF_SIZE;
+
+ ValueStr = ShellCommandLineGetValue (CheckPackage, L"-s");
+ if (ValueStr != NULL) {
+ Context.BufferSize = ShellStrToUintn (ValueStr);
+ if (!Context.BufferSize || Context.BufferSize > MAX_BUF_SIZE) {
+ PRINT_HII_APP (STRING_TOKEN (STR_GEN_PARAM_INV), ValueStr);
+ goto Error;
+ }
+ }
+
+ ValueStr = ShellCommandLineGetValue (CheckPackage, L"-t");
+ if (ValueStr != NULL) {
+ Context.HttpConfigData.TimeOutMillisec = (UINT32)ShellStrToUintn (ValueStr);
+ }
+
+ //
+ // Locate all HTTP Service Binding protocols
+ //
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiManagedNetworkServiceBindingProtocolGuid,
+ NULL,
+ &HandleCount,
+ &Handles
+ );
+ if (EFI_ERROR (Status) || (HandleCount == 0)) {
+ PRINT_HII (STRING_TOKEN (STR_HTTP_ERR_NO_NIC), NULL);
+ if (!EFI_ERROR (Status)) {
+ Status = EFI_NOT_FOUND;
+ }
+
+ goto Error;
+ }
+
+ Status = EFI_NOT_FOUND;
+
+ Context.Flags = 0;
+ if (ShellCommandLineGetFlag (CheckPackage, L"-m")) {
+ Context.Flags |= DL_FLAG_TIME;
+ }
+
+ if (ShellCommandLineGetFlag (CheckPackage, L"-k")) {
+ Context.Flags |= DL_FLAG_KEEP_BAD;
+ }
+
+ for (NicNumber = 0;
+ (NicNumber < HandleCount) && (Status != EFI_SUCCESS);
+ NicNumber++)
+ {
+ ControllerHandle = Handles[NicNumber];
+
+ Status = GetNicName (ControllerHandle, NicNumber, NicName);
+ if (EFI_ERROR (Status)) {
+ PRINT_HII (STRING_TOKEN (STR_HTTP_ERR_NIC_NAME), NicNumber, Status);
+ continue;
+ }
+
+ if (UserNicName != NULL) {
+ if (StrCmp (NicName, UserNicName) != 0) {
+ Status = EFI_NOT_FOUND;
+ continue;
+ }
+
+ NicFound = TRUE;
+ }
+
+ Status = DownloadFile (&Context, ControllerHandle, NicName);
+ PRINT_HII (STRING_TOKEN (STR_GEN_CRLF), NULL);
+
+ if (EFI_ERROR (Status)) {
+ PRINT_HII (
+ STRING_TOKEN (STR_HTTP_ERR_DOWNLOAD),
+ RemoteFilePath,
+ NicName,
+ Status
+ );
+ // If a user aborted the operation, do not try another controller.
+ if (Status == EFI_ABORTED) {
+ goto Error;
+ }
+ }
+
+ if (gHttpError) {
+ //
+ // This is not related to connection, so no need to repeat with
+ // another interface.
+ //
+ break;
+ }
+ }
+
+ if ((UserNicName != NULL) && (!NicFound)) {
+ PRINT_HII (STRING_TOKEN (STR_HTTP_ERR_NIC_NOT_FOUND), UserNicName);
+ }
+
+Error:
+ ShellCommandLineFreeVarList (CheckPackage);
+ SHELL_FREE_NON_NULL (Handles);
+ SHELL_FREE_NON_NULL (Context.ServerAddrAndProto);
+ SHELL_FREE_NON_NULL (Context.URI);
+
+ return Status & ~MAX_BIT;
+}
+
+/**
+ Check and convert the UINT16 option values of the 'http' command
+
+ @param[in] ValueStr Value as an Unicode encoded string
+ @param[out] Value UINT16 value
+
+ @return TRUE The value was returned.
+ @return FALSE A parsing error occured.
+**/
+STATIC
+BOOLEAN
+StringToUint16 (
+ IN CONST CHAR16 *ValueStr,
+ OUT UINT16 *Value
+ )
+{
+ UINTN Val;
+
+ Val = ShellStrToUintn (ValueStr);
+ if (Val > MAX_UINT16) {
+ PRINT_HII_APP (STRING_TOKEN (STR_GEN_PARAM_INV), ValueStr);
+ return FALSE;
+ }
+
+ *Value = (UINT16)Val;
+ return TRUE;
+}
+
+/**
+ Get the name of the NIC.
+
+ @param[in] ControllerHandle The network physical device handle.
+ @param[in] NicNumber The network physical device number.
+ @param[out] NicName Address where to store the NIC name.
+ The memory area has to be at least
+ IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH
+ double byte wide.
+
+ @return EFI_SUCCESS The name of the NIC was returned.
+ @return Others The creation of the child for the Managed
+ Network Service failed or the opening of
+ the Managed Network Protocol failed or
+ the operational parameters for the
+ Managed Network Protocol could not be
+ read.
+**/
+STATIC
+EFI_STATUS
+GetNicName (
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NicNumber,
+ OUT CHAR16 *NicName
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE MnpHandle;
+ EFI_MANAGED_NETWORK_PROTOCOL *Mnp;
+ EFI_SIMPLE_NETWORK_MODE SnpMode;
+
+ Status = CreateServiceChildAndOpenProtocol (
+ ControllerHandle,
+ &gEfiManagedNetworkServiceBindingProtocolGuid,
+ &gEfiManagedNetworkProtocolGuid,
+ &MnpHandle,
+ (VOID**)&Mnp
+ );
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+
+ Status = Mnp->GetModeData (Mnp, NULL, &SnpMode);
+ if (EFI_ERROR (Status) && (Status != EFI_NOT_STARTED)) {
+ goto Error;
+ }
+
+ UnicodeSPrint (
+ NicName,
+ IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH,
+ SnpMode.IfType == NET_IFTYPE_ETHERNET ? L"eth%d" : L"unk%d",
+ NicNumber
+ );
+
+ Status = EFI_SUCCESS;
+
+Error:
+
+ if (MnpHandle != NULL) {
+ CloseProtocolAndDestroyServiceChild (
+ ControllerHandle,
+ &gEfiManagedNetworkServiceBindingProtocolGuid,
+ &gEfiManagedNetworkProtocolGuid,
+ MnpHandle
+ );
+ }
+
+ return Status;
+}
+
+/**
+ Create a child for the service identified by its service binding protocol GUID
+ and get from the child the interface of the protocol identified by its GUID.
+
+ @param[in] ControllerHandle Controller handle.
+ @param[in] ServiceBindingProtocolGuid Service binding protocol GUID of the
+ service to be created.
+ @param[in] ProtocolGuid GUID of the protocol to be open.
+ @param[out] ChildHandle Address where the handler of the
+ created child is returned. NULL is
+ returned in case of error.
+ @param[out] Interface Address where a pointer to the
+ protocol interface is returned in
+ case of success.
+
+ @return EFI_SUCCESS The child was created and the protocol opened.
+ @return Others Either the creation of the child or the opening
+ of the protocol failed.
+**/
+STATIC
+EFI_STATUS
+CreateServiceChildAndOpenProtocol (
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_GUID *ServiceBindingProtocolGuid,
+ IN EFI_GUID *ProtocolGuid,
+ OUT EFI_HANDLE *ChildHandle,
+ OUT VOID **Interface
+ )
+{
+ EFI_STATUS Status;
+
+ *ChildHandle = NULL;
+ Status = NetLibCreateServiceChild (
+ ControllerHandle,
+ gImageHandle,
+ ServiceBindingProtocolGuid,
+ ChildHandle
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = gBS->OpenProtocol (
+ *ChildHandle,
+ ProtocolGuid,
+ Interface,
+ gImageHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ NetLibDestroyServiceChild (
+ ControllerHandle,
+ gImageHandle,
+ ServiceBindingProtocolGuid,
+ *ChildHandle
+ );
+ *ChildHandle = NULL;
+ }
+ }
+
+ return Status;
+}
+
+/**
+ Close the protocol identified by its GUID on the child handle of the service
+ identified by its service binding protocol GUID, then destroy the child
+ handle.
+
+ @param[in] ControllerHandle Controller handle.
+ @param[in] ServiceBindingProtocolGuid Service binding protocol GUID of the
+ service to be destroyed.
+ @param[in] ProtocolGuid GUID of the protocol to be closed.
+ @param[in] ChildHandle Handle of the child to be destroyed.
+
+**/
+STATIC
+VOID
+CloseProtocolAndDestroyServiceChild (
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_GUID *ServiceBindingProtocolGuid,
+ IN EFI_GUID *ProtocolGuid,
+ IN EFI_HANDLE ChildHandle
+ )
+{
+ gBS->CloseProtocol (
+ ChildHandle,
+ ProtocolGuid,
+ gImageHandle,
+ ControllerHandle
+ );
+
+ NetLibDestroyServiceChild (
+ ControllerHandle,
+ gImageHandle,
+ ServiceBindingProtocolGuid,
+ ChildHandle
+ );
+}
+
+/**
+ Wait until operation completes. Completion is indicated by
+ setting of an appropriate variable.
+
+ @param[in] Context A pointer to the HTTP download context.
+ @param[in] CallBackComplete A pointer to the callback completion
+ variable set by the callback.
+
+ @return EFI_SUCCESS Callback signalled completion.
+ @return EFI_TIMEOUT Timed out waiting for completion.
+ @return Others Error waiting for completion.
+**/
+STATIC
+EFI_STATUS
+WaitForCompletion (
+ IN HTTP_DOWNLOAD_CONTEXT *Context,
+ IN OUT BOOLEAN *CallBackComplete
+ )
+{
+ EFI_STATUS Status;
+ EFI_EVENT WaitEvt;
+
+ Status = EFI_SUCCESS;
+
+ // Use a timer to measure timeout. Cannot use Stall here!
+ Status = gBS->CreateEvent (
+ EVT_TIMER,
+ TPL_CALLBACK,
+ NULL,
+ NULL,
+ &WaitEvt
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (!EFI_ERROR (Status)) {
+ Status = gBS->SetTimer (
+ WaitEvt,
+ TimerRelative,
+ EFI_TIMER_PERIOD_SECONDS (TIMER_MAX_TIMEOUT_S)
+ );
+
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ while (! *CallBackComplete
+ && (!EFI_ERROR (Status))
+ && EFI_ERROR (gBS->CheckEvent (WaitEvt)))
+ {
+ Status = Context->Http->Poll (Context->Http);
+ if (!Context->ContentDownloaded
+ && CallBackComplete == &gResponseCallbackComplete)
+ {
+ //
+ // An HTTP server may just send a response redirection header.
+ // In this case, don't wait for the event as
+ // it might never happen and we waste 10s waiting.
+ // Note that at this point Response may not has been populated,
+ // so it needs to be checked first.
+ //
+ if (Context->ResponseToken.Message
+ && Context->ResponseToken.Message->Data.Response
+ && (NEED_REDIRECTION (
+ Context->ResponseToken.Message->Data.Response->StatusCode
+ )
+ ))
+ {
+ break;
+ }
+ }
+ }
+
+ gBS->SetTimer (WaitEvt, TimerCancel, 0);
+ gBS->CloseEvent (WaitEvt);
+
+ if (*CallBackComplete) {
+ return EFI_SUCCESS;
+ }
+
+ if (!EFI_ERROR (Status)) {
+ Status = EFI_TIMEOUT;
+ }
+
+ return Status;
+}
+
+/**
+ Generate and send a request to the http server.
+
+ @param[in] Context HTTP download context.
+ @param[in] DownloadUrl Fully qualified URL to be downloaded.
+
+ @return EFI_SUCCESS Request has been sent successfully.
+ @return EFI_INVALID_PARAMETER Invalid URL.
+ @return EFI_OUT_OF_RESOURCES Out of memory.
+ @return EFI_DEVICE_ERROR If HTTPS is used, this probably
+ means that TLS support either was not
+ installed or not configured.
+ @return Others Error sending the request.
+**/
+
+STATIC
+EFI_STATUS
+SendRequest (
+ IN HTTP_DOWNLOAD_CONTEXT *Context,
+ IN CHAR16 *DownloadUrl
+ )
+{
+ EFI_HTTP_REQUEST_DATA RequestData;
+ EFI_HTTP_HEADER RequestHeader[HDR_MAX];
+ EFI_HTTP_MESSAGE RequestMessage;
+ EFI_STATUS Status;
+ CHAR16 *Host;
+ UINTN StringSize;
+
+ ZeroMem (&RequestData, sizeof (RequestData));
+ ZeroMem (&RequestHeader, sizeof (RequestHeader));
+ ZeroMem (&RequestMessage, sizeof (RequestMessage));
+ ZeroMem (&Context->RequestToken, sizeof (Context->RequestToken));
+
+ RequestHeader[HDR_HOST].FieldName = "Host";
+ RequestHeader[HDR_CONN].FieldName = "Connection";
+ RequestHeader[HDR_AGENT].FieldName = "User-Agent";
+
+ Host = (CHAR16 *)Context->ServerAddrAndProto;
+ while (*Host != CHAR_NULL && *Host != L'/') {
+ Host++;
+ }
+
+ if (*Host == CHAR_NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Get the next slash
+ //
+ Host++;
+ //
+ // And now the host name
+ //
+ Host++;
+
+ StringSize = StrLen (Host) + 1;
+ RequestHeader[HDR_HOST].FieldValue = AllocatePool (StringSize);
+ if (!RequestHeader[HDR_HOST].FieldValue) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ UnicodeStrToAsciiStrS (
+ Host,
+ RequestHeader[HDR_HOST].FieldValue,
+ StringSize
+ );
+
+ RequestHeader[HDR_CONN].FieldValue = "close";
+ RequestHeader[HDR_AGENT].FieldValue = USER_AGENT_HDR;
+ RequestMessage.HeaderCount = HDR_MAX;
+
+ RequestData.Method = HttpMethodGet;
+ RequestData.Url = DownloadUrl;
+
+ RequestMessage.Data.Request = &RequestData;
+ RequestMessage.Headers = RequestHeader;
+ RequestMessage.BodyLength = 0;
+ RequestMessage.Body = NULL;
+ Context->RequestToken.Event = NULL;
+
+ //
+ // Completion callback event to be set when Request completes.
+ //
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ RequestCallback,
+ Context,
+ &Context->RequestToken.Event
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Context->RequestToken.Status = EFI_SUCCESS;
+ Context->RequestToken.Message = &RequestMessage;
+ gRequestCallbackComplete = FALSE;
+ Status = Context->Http->Request (Context->Http, &Context->RequestToken);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+
+ Status = WaitForCompletion (Context, &gRequestCallbackComplete);
+ if (EFI_ERROR (Status)) {
+ Context->Http->Cancel (Context->Http, &Context->RequestToken);
+ }
+
+Error:
+ SHELL_FREE_NON_NULL (RequestHeader[HDR_HOST].FieldValue);
+ if (Context->RequestToken.Event) {
+ gBS->CloseEvent (Context->RequestToken.Event);
+ ZeroMem (&Context->RequestToken, sizeof (Context->RequestToken));
+ }
+
+ return Status;
+}
+
+/**
+ Update the progress of a file download
+ This procedure is called each time a new HTTP body portion is received.
+
+ @param[in] Context HTTP download context.
+ @param[in] DownloadLen Portion size, in bytes.
+ @param[in] Buffer The pointer to the parsed buffer.
+
+ @retval EFI_SUCCESS Portion saved.
+ @retval Other Error saving the portion.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SavePortion (
+ IN HTTP_DOWNLOAD_CONTEXT *Context,
+ IN UINTN DownloadLen,
+ IN CHAR8 *Buffer
+ )
+{
+ CHAR16 Progress[HTTP_PROGRESS_MESSAGE_SIZE];
+ UINTN NbOfKb;
+ UINTN Index;
+ UINTN LastStep;
+ UINTN Step;
+ EFI_STATUS Status;
+
+ LastStep = 0;
+ Step = 0;
+
+ ShellSetFilePosition (mFileHandle, Context->LastReportedNbOfBytes);
+ Status = ShellWriteFile (mFileHandle, &DownloadLen, Buffer);
+ if (EFI_ERROR (Status)) {
+ if (Context->ContentDownloaded > 0) {
+ PRINT_HII (STRING_TOKEN (STR_GEN_CRLF), NULL);
+ }
+
+ PRINT_HII (STRING_TOKEN (STR_HTTP_ERR_WRITE), mLocalFilePath, Status);
+ return Status;
+ }
+
+ if (Context->ContentDownloaded == 0) {
+ ShellPrintEx (-1, -1, L"%s 0 Kb", HTTP_PROGR_FRAME);
+ }
+
+ Context->ContentDownloaded += DownloadLen;
+ NbOfKb = Context->ContentDownloaded >> 10;
+
+ Progress[0] = L'\0';
+ if (Context->ContentLength) {
+ LastStep = (Context->LastReportedNbOfBytes * HTTP_PROGRESS_SLIDER_STEPS) /
+ Context->ContentLength;
+ Step = (Context->ContentDownloaded * HTTP_PROGRESS_SLIDER_STEPS) /
+ Context->ContentLength;
+ }
+
+ Context->LastReportedNbOfBytes = Context->ContentDownloaded;
+
+ if (Step <= LastStep) {
+ if (!Context->ContentLength) {
+ //
+ // Update downloaded size, there is no length info available.
+ //
+ ShellPrintEx (-1, -1, L"%s", HTTP_KB);
+ ShellPrintEx (-1, -1, L"%7d Kb", NbOfKb);
+ }
+
+ return EFI_SUCCESS;
+ }
+
+ ShellPrintEx (-1, -1, L"%s", HTTP_PROGRESS_DEL);
+
+ Status = StrCpyS (Progress, HTTP_PROGRESS_MESSAGE_SIZE, HTTP_PROGR_FRAME);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ for (Index = 1; Index < Step; Index++) {
+ Progress[Index] = L'=';
+ }
+
+ if (Step) {
+ Progress[Step] = L'>';
+ }
+
+ UnicodeSPrint (
+ Progress + (sizeof (HTTP_PROGR_FRAME) / sizeof (CHAR16)) - 1,
+ sizeof (Progress) - sizeof (HTTP_PROGR_FRAME),
+ L" %7d Kb",
+ NbOfKb
+ );
+
+
+ ShellPrintEx (-1, -1, L"%s", Progress);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Replace the original Host and URI with Host and URI returned by the
+ HTTP server in 'Location' header (redirection).
+
+ @param[in] Location A pointer to the 'Location' string
+ provided by HTTP server.
+ @param[in] Context A pointer to HTTP download context.
+ @param[in] DownloadUrl Fully qualified HTTP URL.
+
+ @return EFI_SUCCESS Host and URI were successfully set.
+ @return EFI_OUT_OF_RESOURCES Error setting Host or URI.
+**/
+
+STATIC
+EFI_STATUS
+SetHostURI (
+ IN CHAR8 *Location,
+ IN HTTP_DOWNLOAD_CONTEXT *Context,
+ IN CHAR16 *DownloadUrl
+ )
+{
+ EFI_STATUS Status;
+ UINTN StringSize;
+ UINTN FirstStep;
+ UINTN Idx;
+ UINTN Step;
+ CHAR8 *Walker;
+ CHAR16 *Temp;
+ CHAR8 *Tmp;
+ CHAR16 *Url;
+ BOOLEAN IsAbEmptyUrl;
+
+ Tmp = NULL;
+ Url = NULL;
+ IsAbEmptyUrl = FALSE;
+ FirstStep = 0;
+
+ StringSize = (AsciiStrSize (Location) * sizeof (CHAR16));
+ Url = AllocateZeroPool (StringSize);
+ if (!Url) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = AsciiStrToUnicodeStrS (
+ (CONST CHAR8 *)Location,
+ Url,
+ StringSize
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+
+ //
+ // If an HTTP server redirects to the same location more than once,
+ // then stop attempts and tell it is not reachable.
+ //
+ if (!StrCmp (Url, DownloadUrl)) {
+ Status = EFI_NO_MAPPING;
+ goto Error;
+ }
+
+ if (AsciiStrLen (Location) > 2) {
+ // Some servers return 'Location: //server/resource'
+ IsAbEmptyUrl = (Location[0] == '/') && (Location[1] == '/');
+ if (IsAbEmptyUrl) {
+ // Skip first "//"
+ Location += 2;
+ FirstStep = 1;
+ }
+ }
+
+ if (AsciiStrStr (Location, "://") || IsAbEmptyUrl) {
+ Idx = 0;
+ Walker = Location;
+
+ for (Step = FirstStep; Step < 2; Step++) {
+ for (; *Walker != '/' && *Walker != '\0'; Walker++) {
+ Idx++;
+ }
+
+ if (!Step) {
+ //
+ // Skip "//"
+ //
+ Idx += 2;
+ Walker += 2;
+ }
+ }
+
+ Tmp = AllocateZeroPool (Idx + 1);
+ if (!Tmp) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+
+ CopyMem (Tmp, Location, Idx);
+
+ //
+ // Location now points to URI
+ //
+ Location += Idx;
+ StringSize = (Idx + 1) * sizeof (CHAR16);
+
+ SHELL_FREE_NON_NULL (Context->ServerAddrAndProto);
+
+ Temp = AllocateZeroPool (StringSize);
+ if (!Temp) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+
+ Status = AsciiStrToUnicodeStrS (
+ (CONST CHAR8 *)Tmp,
+ Temp,
+ StringSize
+ );
+ if (EFI_ERROR (Status)) {
+ SHELL_FREE_NON_NULL (Temp);
+ goto Error;
+ }
+
+ Idx = 0;
+ if (IsAbEmptyUrl) {
+ Context->ServerAddrAndProto = StrnCatGrow (
+ &Context->ServerAddrAndProto,
+ &Idx,
+ L"http://",
+ StrLen (L"http://")
+ );
+ }
+
+ Context->ServerAddrAndProto = StrnCatGrow (
+ &Context->ServerAddrAndProto,
+ &Idx,
+ Temp,
+ StrLen (Temp)
+ );
+ SHELL_FREE_NON_NULL (Temp);
+ if (!Context->ServerAddrAndProto) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+ }
+
+ SHELL_FREE_NON_NULL (Context->URI);
+
+ StringSize = AsciiStrSize (Location) * sizeof (CHAR16);
+ Context->URI = AllocateZeroPool (StringSize);
+ if (!Context->URI) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+
+ //
+ // Now make changes to the URI part.
+ //
+ Status = AsciiStrToUnicodeStrS (
+ (CONST CHAR8 *)Location,
+ Context->URI,
+ StringSize
+ );
+Error:
+ SHELL_FREE_NON_NULL (Tmp);
+ SHELL_FREE_NON_NULL (Url);
+
+ return Status;
+}
+
+/**
+ Message parser callback.
+ Save a portion of HTTP body.
+
+ @param[in] EventType Type of event. Can be either
+ OnComplete or OnData.
+ @param[in] Data A pointer to the buffer with data.
+ @param[in] Length Data length of this portion.
+ @param[in] Context A pointer to the HTTP download context.
+
+ @return EFI_SUCCESS The portion was processed successfully.
+ @return Other Error returned by SavePortion.
+**/
+
+STATIC
+EFI_STATUS
+EFIAPI
+ParseMsg (
+ IN HTTP_BODY_PARSE_EVENT EventType,
+ IN CHAR8 *Data,
+ IN UINTN Length,
+ IN VOID *Context
+ )
+{
+ if (!Data || (EventType == BodyParseEventOnComplete) || !Context) {
+ return EFI_SUCCESS;
+ }
+
+ return SavePortion (Context, Length, Data);
+}
+
+
+/**
+ Get HTTP server response and collect the whole body as a file.
+ Set appropriate status in Context (REQ_OK, REQ_REPEAT, REQ_ERROR).
+ Note that even if HTTP server returns an error code, it might send
+ the body as well. This body will be collected in the resultant file.
+
+ @param[in] Context A pointer to the HTTP download context.
+ @param[in] DownloadedUrl A pointer to the fully qualified URL to download.
+
+ @return EFI_SUCCESS Valid file. Body successfully collected.
+ @return EFI_HTTP_ERROR Response is a valid HTTP response, but the
+ HTTP server
+ indicated an error (HTTP code >= 400).
+ Response body MAY contain full
+ HTTP server response.
+ @return Others Error getting the reponse from the HTTP server.
+ Response body is not collected.
+**/
+STATIC
+EFI_STATUS
+GetResponse (
+ IN HTTP_DOWNLOAD_CONTEXT *Context,
+ IN CHAR16 *DownloadUrl
+ )
+{
+ EFI_HTTP_RESPONSE_DATA ResponseData;
+ EFI_HTTP_MESSAGE ResponseMessage;
+ EFI_HTTP_HEADER *Header;
+ EFI_STATUS Status;
+ VOID *MsgParser;
+ EFI_TIME StartTime;
+ EFI_TIME EndTime;
+ CONST CHAR16 *Desc;
+ UINTN ElapsedSeconds;
+ BOOLEAN IsTrunked;
+ BOOLEAN CanMeasureTime;
+
+ ZeroMem (&ResponseData, sizeof (ResponseData));
+ ZeroMem (&ResponseMessage, sizeof (ResponseMessage));
+ ZeroMem (&Context->ResponseToken, sizeof (Context->ResponseToken));
+ IsTrunked = FALSE;
+
+ ResponseMessage.Body = Context->Buffer;
+ Context->ResponseToken.Status = EFI_SUCCESS;
+ Context->ResponseToken.Message = &ResponseMessage;
+ Context->ContentLength = 0;
+ Context->Status = REQ_OK;
+ MsgParser = NULL;
+ ResponseData.StatusCode = HTTP_STATUS_UNSUPPORTED_STATUS;
+ ResponseMessage.Data.Response = &ResponseData;
+ Context->ResponseToken.Event = NULL;
+ CanMeasureTime = FALSE;
+ if (Context->Flags & DL_FLAG_TIME) {
+ ZeroMem (&StartTime, sizeof (StartTime));
+ CanMeasureTime = !EFI_ERROR (gRT->GetTime (&StartTime, NULL));
+ }
+
+ do {
+ SHELL_FREE_NON_NULL (ResponseMessage.Headers);
+ ResponseMessage.HeaderCount = 0;
+ gResponseCallbackComplete = FALSE;
+ ResponseMessage.BodyLength = Context->BufferSize;
+
+ if (ShellGetExecutionBreakFlag ()) {
+ Status = EFI_ABORTED;
+ break;
+ }
+
+ if (!Context->ContentDownloaded && !Context->ResponseToken.Event) {
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ ResponseCallback,
+ Context,
+ &Context->ResponseToken.Event
+ );
+ ASSERT_EFI_ERROR (Status);
+ } else {
+ ResponseMessage.Data.Response = NULL;
+ }
+
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ Status = Context->Http->Response (Context->Http, &Context->ResponseToken);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ Status = WaitForCompletion (Context, &gResponseCallbackComplete);
+ if (EFI_ERROR (Status) && ResponseMessage.HeaderCount) {
+ Status = EFI_SUCCESS;
+ }
+
+ if (EFI_ERROR (Status)) {
+ Context->Http->Cancel (Context->Http, &Context->ResponseToken);
+ break;
+ }
+
+ if (!Context->ContentDownloaded) {
+ if (NEED_REDIRECTION (ResponseData.StatusCode)) {
+ //
+ // Need to repeat the request with new Location (server redirected).
+ //
+ Context->Status = REQ_NEED_REPEAT;
+
+ Header = HttpFindHeader (
+ ResponseMessage.HeaderCount,
+ ResponseMessage.Headers,
+ "Location"
+ );
+ if (Header) {
+ Status = SetHostURI (Header->FieldValue, Context, DownloadUrl);
+ if (Status == EFI_NO_MAPPING) {
+ PRINT_HII (
+ STRING_TOKEN (STR_HTTP_ERR_STATUSCODE),
+ Context->ServerAddrAndProto,
+ L"Recursive HTTP server relocation",
+ Context->URI
+ );
+ }
+ } else {
+ //
+ // Bad reply from the server. Server must specify the location.
+ // Indicate that resource was not found, and no body collected.
+ //
+ Status = EFI_NOT_FOUND;
+ }
+
+ Context->Http->Cancel (Context->Http, &Context->ResponseToken);
+ break;
+ }
+
+ //
+ // Init message-body parser by header information.
+ //
+ if (!MsgParser) {
+ Status = HttpInitMsgParser (
+ ResponseMessage.Data.Request->Method,
+ ResponseData.StatusCode,
+ ResponseMessage.HeaderCount,
+ ResponseMessage.Headers,
+ ParseMsg,
+ Context,
+ &MsgParser
+ );
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+ }
+
+ //
+ // If it is a trunked message, rely on the parser.
+ //
+ Header = HttpFindHeader (
+ ResponseMessage.HeaderCount,
+ ResponseMessage.Headers,
+ "Transfer-Encoding"
+ );
+ IsTrunked = (Header && !AsciiStrCmp (Header->FieldValue, "chunked"));
+
+ HttpGetEntityLength (MsgParser, &Context->ContentLength);
+
+ if (ResponseData.StatusCode >= HTTP_STATUS_400_BAD_REQUEST
+ && (ResponseData.StatusCode != HTTP_STATUS_308_PERMANENT_REDIRECT))
+ {
+ //
+ // Server reported an error via Response code.
+ // Collect the body if any.
+ //
+ if (!gHttpError) {
+ gHttpError = TRUE;
+
+ Desc = ErrStatusDesc[ResponseData.StatusCode -
+ HTTP_STATUS_400_BAD_REQUEST];
+ PRINT_HII (
+ STRING_TOKEN (STR_HTTP_ERR_STATUSCODE),
+ Context->ServerAddrAndProto,
+ Desc,
+ Context->URI
+ );
+
+ //
+ // This gives an RFC HTTP error.
+ //
+ Context->Status = ShellStrToUintn (Desc);
+ Status = ENCODE_ERROR (Context->Status);
+ }
+ }
+ }
+
+ // Do NOT try to parse an empty body.
+ if (ResponseMessage.BodyLength || IsTrunked) {
+ Status = HttpParseMessageBody (
+ MsgParser,
+ ResponseMessage.BodyLength,
+ ResponseMessage.Body
+ );
+ }
+ } while (!HttpIsMessageComplete (MsgParser)
+ && !EFI_ERROR (Status)
+ && ResponseMessage.BodyLength);
+
+ if (Context->Status != REQ_NEED_REPEAT
+ && Status == EFI_SUCCESS
+ && CanMeasureTime)
+ {
+ if (!EFI_ERROR (gRT->GetTime (&EndTime, NULL))) {
+ ElapsedSeconds = EfiTimeToEpoch (&EndTime) - EfiTimeToEpoch (&StartTime);
+ Print (
+ L",%a%Lus\n",
+ ElapsedSeconds ? " " : " < ",
+ ElapsedSeconds > 1 ? (UINT64)ElapsedSeconds : 1
+ );
+ }
+ }
+
+ SHELL_FREE_NON_NULL (MsgParser);
+ if (Context->ResponseToken.Event) {
+ gBS->CloseEvent (Context->ResponseToken.Event);
+ ZeroMem (&Context->ResponseToken, sizeof (Context->ResponseToken));
+ }
+
+ return Status;
+}
+
+/**
+ Worker function that downloads the data of a file from an HTTP server given
+ the path of the file and its size.
+
+ @param[in] Context A pointer to the HTTP download context.
+ @param[in] Controllerhandle The handle of the network interface controller
+ @param[in] NicName NIC name
+
+ @retval EFI_SUCCESS The file was downloaded.
+ @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
+ #retval EFI_HTTP_ERROR The server returned a valid HTTP error.
+ Examine the mLocalFilePath file
+ to get error body.
+ @retval Others The downloading of the file from the server
+ failed.
+
+**/
+STATIC
+EFI_STATUS
+DownloadFile (
+ IN HTTP_DOWNLOAD_CONTEXT *Context,
+ IN EFI_HANDLE ControllerHandle,
+ IN CHAR16 *NicName
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 *DownloadUrl;
+ UINTN UrlSize;
+ EFI_HANDLE HttpChildHandle;
+
+ ASSERT (Context);
+ if (!Context) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DownloadUrl = NULL;
+ HttpChildHandle = NULL;
+
+ Context->Buffer = AllocatePool (Context->BufferSize);
+ if (!Context->Buffer) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // OPEN FILE
+ //
+ if (!EFI_ERROR (ShellFileExists (mLocalFilePath))) {
+ ShellDeleteFileByName (mLocalFilePath);
+ }
+
+ Status = ShellOpenFileByName (
+ mLocalFilePath,
+ &mFileHandle,
+ EFI_FILE_MODE_CREATE |
+ EFI_FILE_MODE_WRITE |
+ EFI_FILE_MODE_READ,
+ 0
+ );
+ if (EFI_ERROR (Status)) {
+ PRINT_HII_APP (STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), mLocalFilePath);
+ goto ON_EXIT;
+ }
+
+ do {
+ SHELL_FREE_NON_NULL (DownloadUrl);
+
+ CLOSE_HTTP_HANDLE (ControllerHandle, HttpChildHandle);
+
+ Status = CreateServiceChildAndOpenProtocol (
+ ControllerHandle,
+ &gEfiHttpServiceBindingProtocolGuid,
+ &gEfiHttpProtocolGuid,
+ &HttpChildHandle,
+ (VOID**)&Context->Http
+ );
+
+ if (EFI_ERROR (Status)) {
+ PRINT_HII (STRING_TOKEN (STR_HTTP_ERR_OPEN_PROTOCOL), NicName, Status);
+ goto ON_EXIT;
+ }
+
+ Status = Context->Http->Configure (Context->Http, &Context->HttpConfigData);
+ if (EFI_ERROR (Status)) {
+ PRINT_HII (STRING_TOKEN (STR_HTTP_ERR_CONFIGURE), NicName, Status);
+ goto ON_EXIT;
+ }
+
+ UrlSize = 0;
+ DownloadUrl = StrnCatGrow (
+ &DownloadUrl,
+ &UrlSize,
+ Context->ServerAddrAndProto,
+ StrLen (Context->ServerAddrAndProto)
+ );
+ if (Context->URI[0] != L'/') {
+ DownloadUrl = StrnCatGrow (
+ &DownloadUrl,
+ &UrlSize,
+ L"/",
+ StrLen (Context->ServerAddrAndProto)
+ );
+ }
+
+ DownloadUrl = StrnCatGrow (
+ &DownloadUrl,
+ &UrlSize,
+ Context->URI,
+ StrLen (Context->URI));
+
+ PRINT_HII (STRING_TOKEN (STR_HTTP_DOWNLOADING), DownloadUrl);
+
+ Status = SendRequest (Context, DownloadUrl);
+ if (Status) {
+ goto ON_EXIT;
+ }
+
+ Status = GetResponse (Context, DownloadUrl);
+
+ if (Status) {
+ goto ON_EXIT;
+ }
+
+ } while (Context->Status == REQ_NEED_REPEAT);
+
+ if (Context->Status) {
+ Status = ENCODE_ERROR (Context->Status);
+ }
+
+ON_EXIT:
+ //
+ // CLOSE FILE
+ //
+ if (mFileHandle) {
+ if (EFI_ERROR (Status) && !(Context->Flags & DL_FLAG_KEEP_BAD)) {
+ ShellDeleteFile (&mFileHandle);
+ } else {
+ ShellCloseFile (&mFileHandle);
+ }
+ }
+
+ SHELL_FREE_NON_NULL (DownloadUrl);
+ SHELL_FREE_NON_NULL (Context->Buffer);
+
+ CLOSE_HTTP_HANDLE (ControllerHandle, HttpChildHandle);
+
+ return Status;
+}
+
+/**
+ Retrive HII package list from ImageHandle and publish to HII database.
+
+ @param ImageHandle The image handle of the process.
+
+ @return HII handle.
+**/
+EFI_HII_HANDLE
+InitializeHiiPackage (
+ EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_HII_PACKAGE_LIST_HEADER *PackageList;
+ EFI_HII_HANDLE HiiHandle;
+
+ //
+ // Retrieve HII package list from ImageHandle
+ //
+ Status = gBS->OpenProtocol (
+ ImageHandle,
+ &gEfiHiiPackageListProtocolGuid,
+ (VOID **)&PackageList,
+ ImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+
+ //
+ // Publish HII package list to HII Database.
+ //
+ Status = gHiiDatabase->NewPackageList (
+ gHiiDatabase,
+ PackageList,
+ NULL,
+ &HiiHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+
+ return HiiHandle;
+}
diff --git a/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpApp.c b/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpApp.c
new file mode 100644
index 000000000000..a7d2c27191a2
--- /dev/null
+++ b/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpApp.c
@@ -0,0 +1,61 @@
+/** @file
+ Entrypoint of "http" shell standalone application.
+
+ Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved. <BR>
+ Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2020, Broadcom. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include "Http.h"
+
+/*
+ * String token ID of help message text.
+ * Shell supports to find help message in the resource section of an
+ * application image if * .MAN file is not found.
+ * This global variable is added to make build tool recognizes
+ * that the help string is consumed by user and then build tool will
+ * add the string into the resource section.
+ * Thus the application can use '-?' option to show help message in Shell.
+ */
+GLOBAL_REMOVE_IF_UNREFERENCED
+EFI_STRING_ID mStringHelpTokenId = STRING_TOKEN (STR_GET_HELP_HTTP);
+
+/**
+ Entry point of Http standalone application.
+
+ @param ImageHandle The image handle of the process.
+ @param SystemTable The EFI System Table pointer.
+
+ @retval EFI_SUCCESS Http command is executed sucessfully.
+ @retval EFI_ABORTED HII package was failed to initialize.
+ @retval others Other errors when executing http command.
+**/
+EFI_STATUS
+EFIAPI
+HttpAppInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ SHELL_STATUS ShellStatus;
+
+ mHttpHiiHandle = InitializeHiiPackage (ImageHandle);
+ if (mHttpHiiHandle == NULL) {
+ return EFI_ABORTED;
+ }
+
+ Status = EFI_SUCCESS;
+
+ ShellStatus = RunHttp (ImageHandle, SystemTable);
+
+ HiiRemovePackages (mHttpHiiHandle);
+
+ if (Status != SHELL_SUCCESS) {
+ Status = ENCODE_ERROR (ShellStatus);
+ }
+
+ return Status;
+}
diff --git a/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.c b/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.c
new file mode 100644
index 000000000000..7f59cc74d2a7
--- /dev/null
+++ b/ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.c
@@ -0,0 +1,137 @@
+/** @file
+ Produce "http" shell dynamic command.
+
+ Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved. <BR>
+ Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2020, Broadcom. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include <Protocol/ShellDynamicCommand.h>
+#include "Http.h"
+
+/**
+ This is the shell command handler function pointer callback type. This
+ function handles the command when it is invoked in the shell.
+
+ @param[in] This The instance of the
+ EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
+ @param[in] SystemTable The pointer to the system table.
+ @param[in] ShellParameters The parameters associated with the command.
+ @param[in] Shell The instance of the shell protocol used in
+ the context of processing this command.
+
+ @return EFI_SUCCESS the operation was sucessful
+ @return other the operation failed.
+**/
+SHELL_STATUS
+EFIAPI
+HttpCommandHandler (
+ IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,
+ IN EFI_SYSTEM_TABLE *SystemTable,
+ IN EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
+ IN EFI_SHELL_PROTOCOL *Shell
+ )
+{
+ gEfiShellParametersProtocol = ShellParameters;
+ gEfiShellProtocol = Shell;
+
+ return RunHttp (gImageHandle, SystemTable);
+}
+
+/**
+ This is the command help handler function pointer callback type. This
+ function is responsible for displaying help information for the associated
+ command.
+
+ @param[in] This The instance of the EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
+ @param[in] Language The pointer to the language string to use.
+
+ @return string Pool allocated help string, must be freed by caller
+**/
+CHAR16 *
+EFIAPI
+HttpCommandGetHelp (
+ IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,
+ IN CONST CHAR8 *Language
+ )
+{
+ return HiiGetString (
+ mHttpHiiHandle,
+ STRING_TOKEN (STR_GET_HELP_HTTP),
+ Language
+ );
+}
+
+EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL mHttpDynamicCommand = {
+ HTTP_APP_NAME,
+ HttpCommandHandler,
+ HttpCommandGetHelp
+};
+
+/**
+ Entry point of Http Dynamic Command.
+
+ Produce the DynamicCommand protocol to handle "http" command.
+
+ @param ImageHandle The image handle of the process.
+ @param SystemTable The EFI System Table pointer.
+
+ @retval EFI_SUCCESS Http command is executed sucessfully.
+ @retval EFI_ABORTED HII package was failed to initialize.
+ @retval others Other errors when executing http command.
+**/
+EFI_STATUS
+EFIAPI
+HttpCommandInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ mHttpHiiHandle = InitializeHiiPackage (ImageHandle);
+ if (mHttpHiiHandle == NULL) {
+ return EFI_ABORTED;
+ }
+
+ Status = gBS->InstallProtocolInterface (
+ &ImageHandle,
+ &gEfiShellDynamicCommandProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mHttpDynamicCommand
+ );
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
+
+/**
+ Http driver unload handler.
+
+ @param ImageHandle The image handle of the process.
+
+ @retval EFI_SUCCESS The image is unloaded.
+ @retval Others Failed to unload the image.
+**/
+EFI_STATUS
+EFIAPI
+HttpUnload (
+ IN EFI_HANDLE ImageHandle
+)
+{
+ EFI_STATUS Status;
+
+ Status = gBS->UninstallProtocolInterface (
+ ImageHandle,
+ &gEfiShellDynamicCommandProtocolGuid,
+ &mHttpDynamicCommand
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ HiiRemovePackages (mHttpHiiHandle);
+
+ return EFI_SUCCESS;
+}
diff --git a/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.uni b/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.uni
new file mode 100644
index 000000000000..00cf05deeb5c
--- /dev/null
+++ b/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.uni
@@ -0,0 +1,117 @@
+// /**
+//
+// (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>
+// Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved. <BR>
+// Copyright (c) 2020, Broadcom. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// Module Name:
+//
+// Http.uni
+//
+// Abstract:
+//
+// String definitions for UEFI Shell HTTP command
+//
+//
+// **/
+
+/=#
+
+#langdef en-US "english"
+
+#string STR_GEN_TOO_MANY #language en-US "%H%s%N: Too many arguments. Try help http.\r\n"
+#string STR_GEN_TOO_FEW #language en-US "%H%s%N: Too few arguments. Try help http.\r\n"
+#string STR_GEN_PARAM_INV #language en-US "%H%s%N: Invalid argument - '%H%s%N'. Try help http.\r\n"
+#string STR_GEN_PROBLEM #language en-US "%H%s%N: Unknown flag - '%H%s%N'. Try help http.\r\n"
+#string STR_GEN_FILE_OPEN_FAIL #language en-US "%H%s%N: Cannot open file - '%H%s%N'\r\n"
+#string STR_GEN_CRLF #language en-US "\r\n"
+
+#string STR_HTTP_ERR_NO_NIC #language en-US "No network interface card found.\r\n"
+#string STR_HTTP_ERR_NIC_NAME #language en-US "Failed to get the name of the network interface card number %d - %r\r\n"
+#string STR_HTTP_ERR_OPEN_PROTOCOL #language en-US "Unable to open HTTP protocol on '%H%s%N' - %r\r\n"
+#string STR_HTTP_ERR_CONFIGURE #language en-US "Unable to configure HTTP protocol on '%H%s%N' - %r\r\n"
+#string STR_HTTP_ERR_DOWNLOAD #language en-US "Unable to download the file '%H%s%N' on '%H%s%N' - %r\r\n"
+#string STR_HTTP_ERR_WRITE #language en-US "Unable to write into file '%H%s%N' - %r\r\n"
+#string STR_HTTP_ERR_NIC_NOT_FOUND #language en-US "Network Interface Card '%H%s%N' not found.\r\n"
+#string STR_HTTP_ERR_STATUSCODE #language en-US "\r'%H%s%N' reports '%s' for '%H%s%N' \r\n"
+#string STR_HTTP_DOWNLOADING #language en-US "Downloading '%H%s%N'\r\n"
+
+#string STR_GET_HELP_HTTP #language en-US ""
+".TH http 0 "Download a file from HTTP server."\r\n"
+".SH NAME\r\n"
+"Download a file from HTTP server.\r\n"
+".SH SYNOPSIS\r\n"
+" \r\n"
+"HTTP [-i interface] [-l port] [-t timeout] [-s size] [-m] [-k]\r\n"
+" <URL> [localfilepath]\r\n"
+".SH OPTIONS\r\n"
+" \r\n"
+" -i interface - Specifies an adapter name, i.e., eth0.\r\n"
+" -k Keep the downloaded file even if there was an error.\r\n"
+" If this parameter is not used, the file will be deleted.\r\n"
+" -l port - Specifies the local port number. Default value is 0\r\n"
+" and the port number is automatically assigned.\r\n"
+" -m Measure and report download time (in seconds). \r\n"
+" -s size The size of the download buffer for a chunk, in bytes.\r\n"
+" Default is 32K. Note that larger buffer does not imply\r\n"
+" better speed.\r\n"
+" -t timeout - The number of seconds to wait for completion of\r\n"
+" requests and responses. Default is 0 which is 'automatic'.\r\n"
+" %HURL%N\r\n"
+" Two types of providing of URLs are supported:\r\n"
+" 1. tftp-like, where host and http_uri are separate parameters\r\n"
+" (example: host /host_uri), and\r\n\"
+" 2. wget-like, where host and host_uri is one parameter.\r\n"
+" (example: host/host_uri)\r\n"
+"\r\n"
+" host - Specifies HTTP Server address.\r\n
+ Can be either IPv4 address or 'http (or https)://addr'\r\n
+ Can use addresses resolvable by DNS as well. \r\n
+ Port can be specified after ':' if needed. \r\n
+ By default port 80 is used.\r\n"
+" http_uri - HTTP server URI to download the file.\r\n"
+"\r\n"
+" localfilepath - Local destination file path.\r\n"
+".SH DESCRIPTION\r\n"
+" \r\n"
+"NOTES:\r\n"
+" 1. The HTTP command allows geting of the file specified by its 'http_uri'\r\n"
+" path from the HTTP server specified by its 'host' IPv4 address. If the\r\n"
+" optional 'localfilepath' parameter is provided, the downloaded file is\r\n"
+" stored locally using the provided file path. If the local file path is\r\n"
+" not specified, the file is stored in the current directory using the file\r\n"
+" server's name.\r\n"
+" 2. Before using the HTTP command, the network interface intended to be\r\n"
+" used to retrieve the file must be configured. This configuration may be\r\n"
+" done by means of the 'ifconfig' command.\r\n"
+" 3. If a network interface is defined with the '-i' option then only this\r\n"
+" interface will be used to retrieve the remote file. Otherwise, all network\r\n"
+" interfaces are tried in the order they have been discovered during the\r\n"
+" DXE phase.\r\n"
+".SH EXAMPLES\r\n"
+" \r\n"
+"EXAMPLES:\r\n"
+" * To get the file "dir1/file1.dat" from the HTTP server 192.168.1.1, port 8080, and\r\n"
+" store it as file2.dat in the current directory (use tftp-like URL format) :\r\n"
+" fs0:\> http 192.168.1.1:8080 dir1/file1.dat file2.dat\r\n"
+" * To get the file /image.bin via HTTPS from server 192.168.1.1 at port 443 \r\n"
+" (default HTTPS port), and store it in the current directory: \r\n"
+" fs0:\> http https://192.168.1.1 image.bin\r\n"
+" To get an index file from http://google.com and place it into the \r\n"
+" current directory:\r\n"
+" fs0:\> http google.com index.html\r\n"
+".SH RETURNVALUES\r\n"
+" \r\n"
+"RETURN VALUES:\r\n"
+" SHELL_SUCCESS The action was completed as requested.\r\n"
+" SHELL_INVALID_PARAMETER One of the passed-in parameters was incorrectly\r\n"
+" formatted or its value was out of bounds.\r\n"
+" HTTP_ERROR No EFI errors, but the server reported a status code\r\n"
+" which should be treated as an error. If an error body sent\r\n"
+" by the server, and -k parameter is on command line,
+" the file wil be saved either as localfilepath filename,\r\n"
+" or as an URI name in the current directory.\r\n"
+" If '/' is at the end of the URL, and no locafilepath filename\r\n"
+" is given on the command line, the file will be retrieved as\r\n"
+" index.html.\r\n"
--
2.28.0.394.ge197136389


[PATCH v12 0/1] ShellPkg/DynamicCommand: add HttpDynamicCommand

Vladimir Olovyannikov
 

Signed-off-by: Vladimir Olovyannikov <vladimir.olovyannikov@broadcom.com>
Cc: Zhichao Gao <zhichao.gao@intel.com>
Cc: Maciej Rabeda <maciej.rabeda@linux.intel.com>
Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Nd <nd@arm.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Samer El-Haj-Mahmoud <Samer.El-Haj-Mahmoud@arm.com>

This patchset introduces an http client utilizing EDK2 HTTP protocol, to
allow fast image downloading from http/https servers.
HTTP download speed is usually faster than tftp.
The client is based on the same approach as tftp dynamic command, and
uses the same UEFI Shell command line parameters. This makes it easy
integrating http into existing UEFI Shell scripts.
Note that to enable HTTP download, feature Pcd
gEfiNetworkPkgTokenSpaceGuid.PcdAllowHttpConnections must be set to TRUE.

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

PATCH v12 changes:
Address comments from Laszlo, Zhichao:
- do not use TimeBaseLib library until it is passes MS VS x64 build
(BZ https://bugzilla.tianocore.org/show_bug.cgi?id=2962);
- change the return type of EfiTimeToEpoch() to UINTN;
- drop the final UINT32 case from EfiTimeToEpoch();
- change the type of ElapsedSeconds to UINTN;
- print the number of elapsed seconds with %Lu specifier.


Vladimir Olovyannikov (1):
ShellPkg/DynamicCommand: add HttpDynamicCommand

ShellPkg/ShellPkg.dec | 1 +
ShellPkg/ShellPkg.dsc | 5 +
.../HttpDynamicCommand/HttpApp.inf | 58 +
.../HttpDynamicCommand/HttpDynamicCommand.inf | 63 +
.../DynamicCommand/HttpDynamicCommand/Http.h | 90 +
ShellPkg/Include/Guid/ShellLibHiiGuid.h | 5 +
.../DynamicCommand/HttpDynamicCommand/Http.c | 1843 +++++++++++++++++
.../HttpDynamicCommand/HttpApp.c | 61 +
.../HttpDynamicCommand/HttpDynamicCommand.c | 137 ++
.../HttpDynamicCommand/Http.uni | 117 ++
10 files changed, 2380 insertions(+)
create mode 100644 ShellPkg/DynamicCommand/HttpDynamicCommand/HttpApp.inf
create mode 100644 ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.inf
create mode 100644 ShellPkg/DynamicCommand/HttpDynamicCommand/Http.h
create mode 100644 ShellPkg/DynamicCommand/HttpDynamicCommand/Http.c
create mode 100644 ShellPkg/DynamicCommand/HttpDynamicCommand/HttpApp.c
create mode 100644 ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.c
create mode 100644 ShellPkg/DynamicCommand/HttpDynamicCommand/Http.uni

--
2.28.0.394.ge197136389


Re: [PATCH] OvmfPkg/README: HTTPS Boot: describe host-side TLS cipher suites forwarding

Philippe Mathieu-Daudé <philmd@...>
 

Hi Laszlo,

On 9/10/20 8:02 AM, Laszlo Ersek wrote:
On 09/09/20 18:21, Philippe Mathieu-Daudé wrote:
On 9/7/20 6:18 PM, Laszlo Ersek wrote:
In QEMU commit range 4abf70a661a5..69699f3055a5, Phil implemented a QEMU
facility for exposing the host-side TLS cipher suite configuration to
OVMF. The purpose is to control the permitted ciphers in the guest's UEFI
HTTPS boot. This complements the forwarding of the host-side crypto policy
from the host to the guest -- the other facet was the set of CA
certificates (for which p11-kit patches had been upstreamed, on the host
side).

Mention the new command line options in "OvmfPkg/README".

Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Gary Lin <glin@suse.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Philippe Mathieu-Daudé <philmd@redhat.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2852
Thanks for addressing this BZ for me...

Signed-off-by: Laszlo Ersek <lersek@redhat.com>
---
OvmfPkg/README | 24 ++++++++++++--------
1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/OvmfPkg/README b/OvmfPkg/README
index 3dd28474ead4..2009d9d29796 100644
--- a/OvmfPkg/README
+++ b/OvmfPkg/README
@@ -294,67 +294,73 @@ and encrypted connection.

You can also append a certificate to the existing list with the following
command:

efisiglist -i <old certdb> -a <cert file> -o <new certdb>

NOTE: You may need the patch to make efisiglist generate the correct header.
(https://github.com/rhboot/pesign/pull/40)

* Besides the trusted certificates, it's also possible to configure the trusted
cipher suites for HTTPS through another fw_cfg entry: etc/edk2/https/ciphers.

- -fw_cfg name=etc/edk2/https/ciphers,file=<cipher suites>
-
OVMF expects a binary UINT16 array which comprises the cipher suites HEX
IDs(*4). If the cipher suite list is given, OVMF will choose the cipher
suite from the intersection of the given list and the built-in cipher
suites. Otherwise, OVMF just chooses whatever proper cipher suites from the
built-in ones.

- While the tool(*5) to create the cipher suite array is still under
- development, the array can be generated with the following script:
+ Using QEMU 5.1 or later, QEMU can expose the ordered list of permitted TLS
+ cipher suites from the host side to OVMF:
+
+ -object tls-cipher-suites,id=mysuite0,priority=@SYSTEM \
+ -fw_cfg name=etc/edk2/https/ciphers,gen_id=mysuite0
+
+ (Refer to the QEMU manual and to
+ <https://gnutls.org/manual/html_node/Priority-Strings.html> for more
+ information on the "priority" property.)
+
+ Using QEMU 5.0 or earlier, the array has to be passed from a file:
What about using a '-' to list each "Using QEMU ..." and make the
separation clearer?
I can do that, yes. There are three possibilities:

- prefix just one line (in each affected paragraph) with the hyphen,

- prefix the first line of each paragraph with the hyphen, plus indent
the rest of the *same paragraph* by 2 spaces.
I'd go with this possibility. Clear and easy.


- prefix the first line of each paragraph with the hyphen, plus indent
the rest of the *text* that applies to the QEMU versions being discussed.
(Note that would be my *visual* preference, but I don't think it's
worth it, I prefer we keep the diff short and easy to review).


Which one do you prefer?

Thanks,
Laszlo


Regardless:
Reviewed-by: Philippe Mathieu-Daude <philmd@redhat.com>
Tested-by: Philippe Mathieu-Daude <philmd@redhat.com>

+
+ -fw_cfg name=etc/edk2/https/ciphers,file=<cipher suites>
+
+ whose contents can be generated with the following script, for example:

export LC_ALL=C
openssl ciphers -V \
| sed -r -n \
-e 's/^ *0x([0-9A-F]{2}),0x([0-9A-F]{2}) - .*$/\\\\x\1 \\\\x\2/p' \
| xargs -r -- printf -- '%b' > ciphers.bin

This script creates ciphers.bin that contains all the cipher suite IDs
supported by openssl according to the local host configuration.

You may want to enable only a limited set of cipher suites. Then, you
should check the validity of your list first:

openssl ciphers -V <cipher list>

If all the cipher suites in your list map to the proper HEX IDs, go ahead
to modify the script and execute it:

export LC_ALL=C
openssl ciphers -V <cipher list> \
| sed -r -n \
-e 's/^ *0x([0-9A-F]{2}),0x([0-9A-F]{2}) - .*$/\\\\x\1 \\\\x\2/p' \
| xargs -r -- printf -- '%b' > ciphers.bin

-* In the future (after release 2.12), QEMU should populate both above fw_cfg
- files automatically from the local host configuration, and enable the user
- to override either with dedicated options or properties.
-
(*1) See "31.4.1 Signature Database" in UEFI specification 2.7 errata A.
(*2) p11-kit: https://github.com/p11-glue/p11-kit/
(*3) efisiglist: https://github.com/rhboot/pesign/blob/master/src/efisiglist.c
(*4) https://wiki.mozilla.org/Security/Server_Side_TLS#Cipher_names_correspondence_table
-(*5) update-crypto-policies: https://gitlab.com/redhat-crypto/fedora-crypto-policies

=== OVMF Flash Layout ===

Like all current IA32/X64 system designs, OVMF's firmware device (rom/flash)
appears in QEMU's physical address space just below 4GB (0x100000000).

OVMF supports building a 1MB, 2MB or 4MB flash image (see the DSC files for the
FD_SIZE_1MB, FD_SIZE_2MB, FD_SIZE_4MB build defines). The base address for the
1MB image in QEMU physical memory is 0xfff00000. The base address for the 2MB
image is 0xffe00000. The base address for the 4MB image is 0xffc00000.

Using the 1MB or 2MB image, the layout of the firmware device in memory looks


Re: [PATCH v7 00/14] Add the VariablePolicy feature

Dandan Bi
 

Hi Bret,

The V7 version is OK from my side. Reviewed-by: Dandan Bi <dandan.bi@intel.com>
Please hold to see if any comments from other reviewers.


Hi Jiewen and Jian,

Do you have any comments?



Thanks,
Dandan

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Bret
Barkelew
Sent: Friday, August 28, 2020 1:51 PM
To: devel@edk2.groups.io
Cc: Yao, Jiewen <jiewen.yao@intel.com>; Chao Zhang
<chao.b.zhang@intel.com>; Wang, Jian J <jian.j.wang@intel.com>; Wu, Hao
A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>; Justen,
Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>;
Ard Biesheuvel <ard.biesheuvel@arm.com>; Andrew Fish
<afish@apple.com>; Ni, Ray <ray.ni@intel.com>
Subject: [edk2-devel] [PATCH v7 00/14] Add the VariablePolicy feature

The 14 patches in this series add the VariablePolicy feature to the core,
deprecate Edk2VarLock (while adding a compatibility layer to reduce code
churn), and integrate the VariablePolicy libraries and protocols into Variable
Services.

Since the integration requires multiple changes, including adding libraries, a
protocol, an SMI communication handler, and VariableServices integration,
the patches are broken up by individual library additions and then a final
integration. Security-sensitive changes like bypassing Authenticated Variable
enforcement are also broken out into individual patches so that attention can
be called directly to them.

Platform porting instructions are described in this wiki entry:
https://github.com/tianocore/tianocore.github.io/wiki/VariablePolicy-
Protocol---Enhanced-Method-for-Managing-Variables#platform-porting

Discussion of the feature can be found in multiple places throughout the last
year on the RFC channel, staging branches, and in devel.

Most recently, this subject was discussed in this thread:
https://edk2.groups.io/g/devel/message/53712
(the code branches shared in that discussion are now out of date, but the
whitepapers and discussion are relevant).

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Chao Zhang <chao.b.zhang@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Hao A Wu <hao.a.wu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Andrew Fish <afish@apple.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Bret Barkelew <brbarkel@microsoft.com>
Signed-off-by: Bret Barkelew <brbarkel@microsoft.com>

v7 changes:
* Address comments from Dandan about security of the MM handler
* Add readme
* Fix bug around hex characters in BOOT####, etc
* Add additional testing for hex characters
* Add additional testing for authenticated variables

v6 changes:
* Fix an issue with uninitialized Status in InitVariablePolicyLib() and
DeinitVariablePolicyLib()
* Fix GCC building in shell-based functional test
* Rebase on latest origin/master

v5 changes:
* Fix the CONST mismatch in VariablePolicy.h and VariablePolicySmmDxe.c
* Fix EFIAPI mismatches in the functional unittest
* Rebase on latest origin/master

v4 changes:
* Remove Optional PcdAllowVariablePolicyEnforcementDisable PCD from
platforms
* Rebase on master
* Migrate to new MmCommunicate2 protocol
* Fix an oversight in the default return value for
InitMmCommonCommBuffer
* Fix in VariablePolicyLib to allow ExtraInitRuntimeDxe to consume variables

V3 changes:
* Address all non-unittest issues with ECC
* Make additional style changes
* Include section name in hunk headers in "ini-style" files
* Remove requirement for the EdkiiPiSmmCommunicationsRegionTable
driver
(now allocates its own buffer)
* Change names from VARIABLE_POLICY_PROTOCOL and
gVariablePolicyProtocolGuid
to EDKII_VARIABLE_POLICY_PROTOCOL and
gEdkiiVariablePolicyProtocolGuid
* Fix GCC warning about initializing externs
* Add UNI strings for new PCD
* Add patches for ArmVirtPkg, OvmfXen, and UefiPayloadPkg
* Reorder patches according to Liming's feedback about adding to platforms
before changing variable driver

V2 changes:
* Fixed implementation for RuntimeDxe
* Add PCD to block DisableVariablePolicy
* Fix the DumpVariablePolicy pagination in SMM


Bret Barkelew (14):
MdeModulePkg: Define the VariablePolicy protocol interface
MdeModulePkg: Define the VariablePolicyLib
MdeModulePkg: Define the VariablePolicyHelperLib
MdeModulePkg: Define the VarCheckPolicyLib and SMM interface
OvmfPkg: Add VariablePolicy engine to OvmfPkg platform
EmulatorPkg: Add VariablePolicy engine to EmulatorPkg platform
ArmVirtPkg: Add VariablePolicy engine to ArmVirtPkg platform
UefiPayloadPkg: Add VariablePolicy engine to UefiPayloadPkg platform
MdeModulePkg: Connect VariablePolicy business logic to
VariableServices
MdeModulePkg: Allow VariablePolicy state to delete protected variables
SecurityPkg: Allow VariablePolicy state to delete authenticated
variables
MdeModulePkg: Change TCG MOR variables to use VariablePolicy
MdeModulePkg: Drop VarLock from RuntimeDxe variable driver
MdeModulePkg: Add a shell-based functional test for VariablePolicy

MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c
| 345 +++
MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.c
| 396 ++++
MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitNull.c
| 46 +

MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitRuntimeDx
e.c | 85 +
MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
| 830 +++++++

MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/VariablePo
licyUnitTest.c | 2452 ++++++++++++++++++++

MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFu
ncTestApp.c | 2226 ++++++++++++++++++
MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockDxe.c
| 52 +-
MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c
| 60 +-
MdeModulePkg/Universal/Variable/RuntimeDxe/VarCheck.c
| 49 +-
MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c
| 53 +

MdeModulePkg/Universal/Variable/RuntimeDxe/VariableLockRequstToLock
.c | 71 +
MdeModulePkg/Universal/Variable/RuntimeDxe/VariablePolicySmmDxe.c
| 642 +++++

MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.
c | 14 +
SecurityPkg/Library/AuthVariableLib/AuthService.c | 22
+-
ArmVirtPkg/ArmVirt.dsc.inc | 4 +
EmulatorPkg/EmulatorPkg.dsc | 3 +
MdeModulePkg/Include/Guid/VarCheckPolicyMmi.h |
54 +
MdeModulePkg/Include/Library/VariablePolicyHelperLib.h
| 164 ++
MdeModulePkg/Include/Library/VariablePolicyLib.h |
207 ++
MdeModulePkg/Include/Protocol/VariablePolicy.h |
157 ++
MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.inf
| 42 +
MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.uni
| 12 +
MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
| 35 +
MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.uni
| 12 +
MdeModulePkg/Library/VariablePolicyLib/ReadMe.md |
410 ++++
MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
| 49 +
MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.uni
| 12 +
MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf
| 51 +

MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/VariablePo
licyUnitTest.inf | 45 +
MdeModulePkg/MdeModulePkg.ci.yaml | 8 +-
MdeModulePkg/MdeModulePkg.dec | 26 +-
MdeModulePkg/MdeModulePkg.dsc | 9 +
MdeModulePkg/MdeModulePkg.uni | 7 +
MdeModulePkg/Test/MdeModulePkgHostTest.dsc |
11 +
MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Readme.md
| 55 +

MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFu
ncTestApp.inf | 47 +

MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyTe
stAuthVar.h | 128 +
MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
| 5 +
MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf
| 4 +

MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.i
nf | 11 +

MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf
| 4 +
OvmfPkg/OvmfPkgIa32.dsc | 5 +
OvmfPkg/OvmfPkgIa32X64.dsc | 5 +
OvmfPkg/OvmfPkgX64.dsc | 5 +
OvmfPkg/OvmfXen.dsc | 4 +
SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf |
2 +
UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 4 +
UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 4 +
49 files changed, 8865 insertions(+), 79 deletions(-) create mode 100644
MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c
create mode 100644
MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.c
create mode 100644
MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitNull.c
create mode 100644
MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitRuntimeDx
e.c
create mode 100644
MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
create mode 100644
MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/VariablePo
licyUnitTest.c
create mode 100644
MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFu
ncTestApp.c
create mode 100644
MdeModulePkg/Universal/Variable/RuntimeDxe/VariableLockRequstToLock
.c
create mode 100644
MdeModulePkg/Universal/Variable/RuntimeDxe/VariablePolicySmmDxe.c
create mode 100644 MdeModulePkg/Include/Guid/VarCheckPolicyMmi.h
create mode 100644
MdeModulePkg/Include/Library/VariablePolicyHelperLib.h
create mode 100644 MdeModulePkg/Include/Library/VariablePolicyLib.h
create mode 100644 MdeModulePkg/Include/Protocol/VariablePolicy.h
create mode 100644
MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.inf
create mode 100644
MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.uni
create mode 100644
MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
create mode 100644
MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.uni
create mode 100644 MdeModulePkg/Library/VariablePolicyLib/ReadMe.md
create mode 100644
MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
create mode 100644
MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.uni
create mode 100644
MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf
create mode 100644
MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/VariablePo
licyUnitTest.inf
create mode 100644
MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Readme.md
create mode 100644
MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFu
ncTestApp.inf
create mode 100644
MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyTe
stAuthVar.h

--
2.28.0.windows.1



Re: [PATCH edk2-non-osi 1/1] Platform/Qemu/Sbsa: Update ARM-TF binaries with EC and topology

Leif Lindholm
 

On Tue, Sep 15, 2020 at 15:10:27 +0100, Graeme Gregory wrote:
Based on arm-tf commit 1aabb74fae0e30901884b6cb230d7ea730a74344

With https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/5478
applied to support CPU topology used by sbsa-ref machine.

With https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/5479
applied to support the EC device in sbsa-ref machine so reboot/shutdown
function as expected.

Signed-off-by: Graeme Gregory <graeme@nuviainc.com>
Reviewed-by: Leif Lindholm <leif@nuviainc.com>
Pushed as ff6750947db3.

Thanks!

---

Patch available for cherrypick
https://github.com/xXorAa/edk2-non-osi/tree/qemu-sbsa-update-ec-topology-v1

Platform/Qemu/Sbsa/bl1.bin | Bin 19301 -> 19301 bytes
Platform/Qemu/Sbsa/fip.bin | Bin 53973 -> 54002 bytes
2 files changed, 0 insertions(+), 0 deletions(-)

diff --git a/Platform/Qemu/Sbsa/bl1.bin b/Platform/Qemu/Sbsa/bl1.bin
index bd0b2de1dfcb..794f5b68bd13 100755
Binary files a/Platform/Qemu/Sbsa/bl1.bin and b/Platform/Qemu/Sbsa/bl1.bin differ
diff --git a/Platform/Qemu/Sbsa/fip.bin b/Platform/Qemu/Sbsa/fip.bin
index 03b327bcd022..a12cfa5ba2c9 100644
Binary files a/Platform/Qemu/Sbsa/fip.bin and b/Platform/Qemu/Sbsa/fip.bin differ
--
2.25.1


[PATCH edk2-non-osi 1/1] Platform/Qemu/Sbsa: Update ARM-TF binaries with EC and topology

Graeme Gregory <graeme@...>
 

Based on arm-tf commit 1aabb74fae0e30901884b6cb230d7ea730a74344

With https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/5478
applied to support CPU topology used by sbsa-ref machine.

With https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/5479
applied to support the EC device in sbsa-ref machine so reboot/shutdown
function as expected.

Signed-off-by: Graeme Gregory <graeme@nuviainc.com>
---

Patch available for cherrypick
https://github.com/xXorAa/edk2-non-osi/tree/qemu-sbsa-update-ec-topology-v1

Platform/Qemu/Sbsa/bl1.bin | Bin 19301 -> 19301 bytes
Platform/Qemu/Sbsa/fip.bin | Bin 53973 -> 54002 bytes
2 files changed, 0 insertions(+), 0 deletions(-)

diff --git a/Platform/Qemu/Sbsa/bl1.bin b/Platform/Qemu/Sbsa/bl1.bin
index bd0b2de1dfcb..794f5b68bd13 100755
Binary files a/Platform/Qemu/Sbsa/bl1.bin and b/Platform/Qemu/Sbsa/bl1.bin differ
diff --git a/Platform/Qemu/Sbsa/fip.bin b/Platform/Qemu/Sbsa/fip.bin
index 03b327bcd022..a12cfa5ba2c9 100644
Binary files a/Platform/Qemu/Sbsa/fip.bin and b/Platform/Qemu/Sbsa/fip.bin differ
--
2.25.1


Re: [PATCH] NetworkPkg/HttpDxe: Clear TlsChildHandle during cleanup

Maciej Rabeda
 

Hi Scott,

Thanks for submitting the patch - I am about to approve the patch, however - a couple of small remarks to the commit message.
1. Please remove the "From:" line
2. Please add "Cc:" lines before "Signed-off-by". Cc people are added based on appropriate EDK2 package maintainer & reviewer list: https://github.com/tianocore/edk2/blob/master/Maintainers.txt
Example of a patch from NetworkPkg: https://github.com/tianocore/edk2/commit/0716b2390f005e84961cb98af28bd16cdcc5db42

Thanks,
Maciej

On 08-Sep-20 06:50, D Scott Phillips wrote:
On Monday, September 7, 2020 4:33 AM, Laszlo Ersek <lersek@...> wrote:

Hi Scott,

(+Rebecca)

On 09/05/20 03:15, D Scott Phillips wrote:

From: D Scott Phillips d.scott.phillips@...
Leaving TlsChildHandle with the stale handle causes later use of https
with the http instance to incorrectly skip tls reconfiguration, use
the stale handle, and eventually call a garbage function pointer.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1917
Signed-off-by: D Scott Phillips d.scott.phillips@...

------------------------------------------------------------------------------------------------------------------------------

NetworkPkg/HttpDxe/HttpProto.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/NetworkPkg/HttpDxe/HttpProto.c b/NetworkPkg/HttpDxe/HttpProto.c
index 3c7c6ff9f0..afc7db5a72 100644
--- a/NetworkPkg/HttpDxe/HttpProto.c
+++ b/NetworkPkg/HttpDxe/HttpProto.c
@@ -873,6 +873,7 @@ HttpCleanProtocol (
// Destroy the TLS instance.
//
HttpInstance->TlsSb->DestroyChild (HttpInstance->TlsSb, HttpInstance->TlsChildHandle);

-   HttpInstance->TlsChildHandle = NULL;
    }


if (HttpInstance->Tcp4ChildHandle != NULL) {
thanks a lot for tracking this down!

I've reopened BZ#1917, and linked your patch email in a new comment.

But, I'd also like to assign the BZ to you, if that's OK with you. Can
you please register in the TianoCore bugzilla instance for that?
Certainly, account created and assignment taken. Thanks Laszlo.

Scott






[PATCH edk2-non-osi 1/1] Platform/Qemu/Sbssa: Update ARM-TF binaries with EC and topology

Graeme Gregory <graeme@...>
 

Based on arm-tf commit 1aabb74fae0e30901884b6cb230d7ea730a74344

With https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/5478
applied to support CPU topology used by sbsa-ref machine.

With https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/5479
applied to support the EC device in sbsa-ref machine so reboot/shutdown
function as expected.

Signed-off-by: Graeme Gregory <graeme@nuviainc.com>
---
Platform/Qemu/Sbsa/bl1.bin | Bin 19301 -> 19301 bytes
Platform/Qemu/Sbsa/fip.bin | Bin 53973 -> 54002 bytes
2 files changed, 0 insertions(+), 0 deletions(-)

diff --git a/Platform/Qemu/Sbsa/bl1.bin b/Platform/Qemu/Sbsa/bl1.bin
index bd0b2de1dfcb23eb3901f3001ab01edd9f15cb52..794f5b68bd13f1383c194b24f18644db9f327b1b 100755
GIT binary patch
delta 3957
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
VO>)Ab7L%K>z|(%O#8=*H{x2QFDrNux

delta 4015
zcmZ`+dvH|M8UN0`cQ<#FKz5UT2eJ=HNFpI24-!Dk%?5d@2y82g%Eka9Xe9(&ZN%IJ
zAJEv!%}K%1Y8FK%yLCoNK)cfi0jZBN+9U%1ILd}s8B;oFisS-u`<=UY8HO3}%-!#N
zzw@2%eCK<eyXSY3^E-(JjBSHq=f3a2oOkkcEq`)`VsVhym7)h)MG?9}096@Cr<$P4
z$@qllGJv2oAoamy#RqWw9-Qk-c=`cAIf4{14WEZN%4;}cJA6>AJcfLri&p};?w2@!
zSb~$=Q122Rx|ZX6Nd&7G<Yj&QD*q`jE&_=tNL5IJr^Z?iN5*(iK#<gS>Latsqx2Cn
zpG>Fk;P@drL@J1h+PDhx9bL#(n^HPlbUT+Hv?&DS!MV>ijGpC5u?K|VFhI~JfKqFQ
zZ|f3?AZ~n$9d6Z%Nu%Dq3t}L^Qtw_db}f-`Fx(qn5c7!8)Pw7A&f*QzbiT!nl2>y<
z?aqXz1qKMNMal1ZF8UGJXg6PxX;WTA*@K*;WA$G8HNT96>2%@u<T?78aBr4fA(@ie
z0C12P<-uvR$S~btR~p*wbd_P6=~O^H^C2jqLAuk>YB>>5SqQH1eDus&^g=%^Fuu0F
zXF)6kP#Gd}HnYDGCHx>~KaTXg>`+3Z0o4QWZJcj+`_ZR?Fj3B2=G4df9Lie)s3^Pa
zXpb0!9}-ooM>#bg{rz7&?^w%UG+&P_Cy~vltLvzpdeZzR-3Z)#QQ8!8jc!USCiV1<
zGzXbO52clI&4gY^o0Q$psmx=wCz8}Z8lbtN%f2BEx)?sza-_$LmTMmFp^L=AhaF1z
zhr})!b56?_nJ5h$s3RGYI@WTuhaFAQ(?AO=<{{FXsR8=jYE-@zoQe$dVnCoOAMuxf
zelD)#ok}sCX{sh)(k9aq@-aPPDz&Fn)!w>wA2p`uS;jCkhZ;eNJ3#ef;{29YrF$&D
zHb58Jc#x%1h?57m(>3YK$z~eE-&J&6Mm1SV@6Pa$g>+3uA+ginWH|75U&azkUcLIS
zvBa(s9*VtaSU8UwGw1%qsR)V0u4c44bkvCzf*#1OSDALKmdk;#Q+XE`h1~V3#>bsn
z5;OUI4Ch=*3#0zz{K)dUNWkl&-I>$KR{D8nqr0G9mGxa^jBp%z&AnbTT|CbJ2(o?X
z<%9U1$DnH!F1Zxu?NqT*E?M~maSqxCIoSIhSIDdJ`ppNtm_RI)OrEV}GMGR+-svh)
zppgD^+$?e*HH@D^258B6Z|ku<g_SQ$sS1>8F83%`azK5PKv$g4iE4&z%vE;Z%8$C0
zoyac-=sJzwnS*2ILXQAVLjnZvLf$4}l=z(DnK=F*&h=qA3^6ye7P7*lyo|UBz`AsZ
zw?&!Yyjuh{p$T4P3u1BJT1@b`Oy&+<CVZ>1*S*Rmbd$Cw<Wn}%iCK>H6NI%b-0EF=
zS5~ey<X1wPuAFEpc~{b>vbGQx9nPBO-|tt-aQb)n1~8YtM?1g7vyrJ%OzV%bi_SKC
zh(K4Gt1O3chIwX_Ms3C0=^k?~Nuz%=mtwhHGCyE7;JIqCB@H>c-L+s{-+*n51}#mQ
zmnSL5a8(KJbBYdFo+SI|UD<BzJr8E*R;@%&4x!$ZfjhK<Pd3*e&Ox7`XeBCuHI)bV
z(Ma|bGM5fye?oxn&hd|X8jHpXk~+j&qdVxQIrB*YwOAdt{_Dv!mw2d(Pr~_nqKI^k
z^$ud7Pgp%B!;QqQxJOdoql$GlDWsoS3%R&NuUa1@chIG_obf&*bPc0P*eUvbHFT4$
zKx9^&;UP-HHk+xYUaiC0=W6KRZS{suUdgGUM*C~y5oh`IOv1DOP$y5{w!c8))bF4~
zrtdrM%yQw)BriLQ=LUFp@N6$}mXQg-DOb@?V=c$DEXKTvVkYkg#JA9UT@#9M(1!h<
ztbiDENgGC+Is7qH<%4!NyBjcY`vX8bT~l-1%0cuWOQ4i*yXk<df?T8qcWFV}3$0&_
zIJ$Sk3MuA;mQEjV(dG#`QD${BN1`mNeH?wr?Y8bA5PShuHFFScm*l}_j*HTMx3!hq
zmSje7V`7k(b#r8W2n~E%7e1VhI&g89(UslJ8Jpr`iC~EP#er^4Xlgb-d!RX6-u(@(
zg*v7OqW{M6Sjz`mv%j*Ei`YT#yxwexTt`pb;0?vz6H<g#tQ9YqtBrhXq#B#k!RM{H
z>INZljVIBrH^E{9TZad@;XOte7@7_0kpIN)5uO~!4Sw|j-hR#P?YmDQwwB|Lk75Ag
z{EX;OHK-p=KCwGqiy^zGpyR?;h@E={V)3;5i#$L!9OWT6_Z2B}rdm?p<|Oqwj_YWH
zR?^W8&f$;%***aVW~9Nu#WV<>=E!gl(f}{10T7M{Ag7}{3+n<s;lYc!&IG~uRw;JK
zkNt;tMFEY9<A!lm?&P5(K3l?T(luOoBN1%IL*P|uW$VItp-ZfB)=KIsfN%D+qO1Ra
zJweKmR6y%xBOD5qO0h=d2`X(Ug%~`)nKlCa(aS+FBuEFs*j~@zsn7F{;vwE06(o6C
zoX?G(oe%0;7&dHZIL7tZUgLPX{}i#)T+Xn3EfHkp&)WKxm4V3B#`;LBx?yhQdh^|p
zv6fG@jO_;d@Dpg1hbP0Lnh1ukCn_6X-Q4+O8@`On*=B6h)P}PVYvt_2=P(!Qa;4Z=
zenK%ba4zD^_ybyw{FUWM?}rmi#PU9N$syj3adbpEgFG0eUrnrai3S*8-&Kux?ru&T
zegY}ui)dAzoH;jNxthyv^J6_ty+`sK#P%m_AXiwyx$zTd7M8^2Enlpmmpqd*FXt;0
z@Y;F_-)VHBcPeqxMc(z64lKR~tX;f*ts$fz(|>r+;*A^e<ys`{be>nnpX{E^pTtHU
zmFP*|BvTcl)%dQW#9umY7IvoX7}*g%FPcy1_;ZcNW)kx|chN`vA#Aya{WhZ+KgY_<
z^lN{GP${W9sB6*#Ste0ZO=jmwQ<<bL^g4T=p5!A$q{`${a)Tb3JZ0h~JV+eB3WUjI
zBl>XHIo=q3(F_AvTe~jx8uIVw3e8@Hh=3u+Z{aYGGxag}6k-N-4;B@skGhd=nbJnw
zy@@ILL~LZ=rU1iqYS9~9y}S2#(F~6J*_2*>>KlZ+ruM#7B68{S;791CPw=HfC7Y>S
zCW!3QphpKfrwiiCINo+s0D-m0tV;=$3*tN+FSsdyKmjs^DS-+>G~!siDS*HQ?BN&j
zWqWp3TE(`eMDVHW2?z44sa%OR;ABrqpbBlk@iv{OG6HLnS(g%+fi~cH!A$`K3XmyG
z2~?vEI2LaTAaDVrc@f`UrFx@CFP9i7k(SWVB6I6rBWO=tNKzp!NmIWUb^Jegect-q
z(D51_AJx}&iAkwfb-G`t=X5II=LLJVCFy#Qbik?8<TOB!zTnSN3el;Y;yG<l^ZgGP
zcmOlrbL{EQNYX+bUpha@ucN+tPhARaNTIh$D?ftoN#UsFJ#=7SQA$%&YUVagZ7H0s
zu%x7uwg50|9H#NQ48dG*6xmapF66n5FHG?$eKjyW#p%*@xAC5Z$%!JJR_Jt&PUkN~
zH7-i;-eC#pDw5PJ0Ii(2sk(gntg@O}73EXCi=KJXJH5hNURGWPKQEtFQMhT%lWQ89
z*A&fSTuFINb;;v1XEs(=R<EtB?EPxqY@WN*huZV9H}+>~VZlGO+Ov(pb}BD&<(A#h
y!luFf1PHeRw1^{)GWT>YHW&5jA=EvKq6uwHdQutmjV41c;sQ_SVu3!q*z|uv9caw}

diff --git a/Platform/Qemu/Sbsa/fip.bin b/Platform/Qemu/Sbsa/fip.bin
index 03b327bcd022a33231b8ffbe5ff516bbfaec7673..a12cfa5ba2c9f5e7523d046f0afec91de5d7f762 100644
GIT binary patch
delta 17262
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

delta 16518
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
EA2nz&P5=M^

--
2.25.1


Re: [PATCH v2 1/2] MdeModulePkg: Fix OptionROM scanning

Laszlo Ersek
 

Anthony, Julien, Rebecca, Peter,

FYI:

On 09/15/20 14:26, Marcello Sylvester Bauer wrote:
From: Patrick Rudolph <patrick.rudolph@9elements.com>

The Option ROM scanner can't work as enumeration was done by the
first stage bootloader. Running it will disable the ability of the
PCIPlatform code to scan for ROMs.

Required for the following patch that enables custom Option ROM
scanning using gPciPlatformProtocol.

Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Signed-off-by: Marcello Sylvester Bauer <marcello.bauer@9elements.com>
Cc: Patrick Rudolph <patrick.rudolph@9elements.com>
Cc: Christian Walter <christian.walter@9elements.com>
Cc: Hao A Wu <hao.a.wu@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
---
MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
index 6c68a97d4e46..7420f0079f7d 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
@@ -2530,10 +2530,12 @@ PciEnumeratorLight (
//
RemoveRejectedPciDevices (RootBridgeDev->Handle, RootBridgeDev);

- //
- // Process option rom light
- //
- ProcessOptionRomLight (RootBridgeDev);
+ if (!PcdGetBool (PcdPciDisableBusEnumeration)) {
+ //
+ // Process option rom light
+ //
+ ProcessOptionRomLight (RootBridgeDev);
+ }

//
// Determine attributes for all devices under this root bridge
I suggest checking the effects of this patch on Xen and bhyve.

Thanks
Laszlo


[PATCH v2 2/2] UefiPayloadPkg: Scan for Option ROMs

Marcello Sylvester Bauer <marcello.bauer@...>
 

From: Patrick Rudolph <patrick.rudolph@9elements.com>

Install the gPciPlatformProtocol to scan for Option ROMs.

For every device we probe the Option ROM and provide a pointer
to the activated BAR if found.

It's safe to assume that all ROM bars have been enumerated,
reserved in the bridge resources and are disabled by default.

Enabling them and leaving them enabled will do no harm.

Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Signed-off-by: Marcello Sylvester Bauer <marcello.bauer@9elements.com>
Cc: Patrick Rudolph <patrick.rudolph@9elements.com>
Cc: Christian Walter <christian.walter@9elements.com>
Cc: Maurice Ma <maurice.ma@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
---
UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 1 +
UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 1 +
UefiPayloadPkg/UefiPayloadPkg.fdf | 1 +
UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.inf | 46 +++
UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.h | 19 +
UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.c | 426 ++++++++++++++++++++
6 files changed, 494 insertions(+)

diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc b/UefiPayloadPkg/UefiPay=
loadPkgIa32.dsc
index 12d7ffe81416..9f42d2cd6b74 100644
--- a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc
+++ b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc
@@ -513,6 +513,7 @@ [Components.IA32]
MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf=0D
!endif=0D
UefiPayloadPkg/GraphicsOutputDxe/GraphicsOutputDxe.inf=0D
+ UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.inf=0D
=0D
#------------------------------=0D
# Build the shell=0D
diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc b/UefiPayloadPkg/Uefi=
PayloadPkgIa32X64.dsc
index 9bae1daa09bb..59fc1b79457b 100644
--- a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc
+++ b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc
@@ -514,6 +514,7 @@ [Components.X64]
MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf=0D
!endif=0D
UefiPayloadPkg/GraphicsOutputDxe/GraphicsOutputDxe.inf=0D
+ UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.inf=0D
=0D
#------------------------------=0D
# Build the shell=0D
diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayload=
Pkg.fdf
index 570a8ee7fdc1..9b188724221d 100644
--- a/UefiPayloadPkg/UefiPayloadPkg.fdf
+++ b/UefiPayloadPkg/UefiPayloadPkg.fdf
@@ -151,6 +151,7 @@ [FV.DXEFV]
INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf=0D
!endif=0D
INF UefiPayloadPkg/GraphicsOutputDxe/GraphicsOutputDxe.inf=0D
+INF UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.inf=0D
=0D
#=0D
# SCSI/ATA/IDE/DISK Support=0D
diff --git a/UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.inf b/UefiPayload=
Pkg/PciPlatformDxe/PciPlatformDxe.inf
new file mode 100644
index 000000000000..96cedad5afc3
--- /dev/null
+++ b/UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.inf
@@ -0,0 +1,46 @@
+## @file=0D
+# This driver produces gEfiPciPlatform protocol to load PCI Option ROMs=0D
+#=0D
+# Copyright (c) 2020, 9elements Agency GmbH=0D
+#=0D
+# SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+#=0D
+#=0D
+##=0D
+=0D
+[Defines]=0D
+ INF_VERSION =3D 0x00010005=0D
+ BASE_NAME =3D PciPlatformDxe=0D
+ FILE_GUID =3D 86D58F7B-6E7C-401F-BDD4-E32E6D582AAD=
=0D
+ MODULE_TYPE =3D UEFI_DRIVER=0D
+ VERSION_STRING =3D 1.0=0D
+ ENTRY_POINT =3D InstallPciPlatformProtocol=0D
+=0D
+#=0D
+# The following information is for reference only and not required by the =
build tools.=0D
+#=0D
+# VALID_ARCHITECTURES =3D IA32 X64=0D
+#=0D
+=0D
+[Sources.common]=0D
+ PciPlatformDxe.h=0D
+ PciPlatformDxe.c=0D
+=0D
+[Packages]=0D
+ MdePkg/MdePkg.dec=0D
+ MdeModulePkg/MdeModulePkg.dec=0D
+=0D
+[LibraryClasses]=0D
+ UefiDriverEntryPoint=0D
+ UefiBootServicesTableLib=0D
+ DxeServicesTableLib=0D
+ DebugLib=0D
+ MemoryAllocationLib=0D
+ BaseMemoryLib=0D
+ DevicePathLib=0D
+ UefiLib=0D
+ HobLib=0D
+=0D
+[Protocols]=0D
+ gEfiPciPlatformProtocolGuid ## PRODUCES=0D
+ gEfiPciIoProtocolGuid ## COMSUMES=0D
diff --git a/UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.h b/UefiPayloadPk=
g/PciPlatformDxe/PciPlatformDxe.h
new file mode 100644
index 000000000000..c40518c703f8
--- /dev/null
+++ b/UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.h
@@ -0,0 +1,19 @@
+/** @file=0D
+ Header file for a PCI platform driver.=0D
+=0D
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>=0D
+SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+=0D
+=0D
+**/=0D
+#ifndef _PCI_PLATFORM_DXE_H_=0D
+#define _PCI_PLATFORM_DXE_H_=0D
+#include <PiDxe.h>=0D
+=0D
+#include <IndustryStandard/Pci.h>=0D
+#include <IndustryStandard/Acpi.h>=0D
+#include <IndustryStandard/Pci22.h>=0D
+#include <Protocol/PciIo.h>=0D
+#include <Protocol/PciPlatform.h>=0D
+=0D
+#endif=0D
diff --git a/UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.c b/UefiPayloadPk=
g/PciPlatformDxe/PciPlatformDxe.c
new file mode 100644
index 000000000000..65a1ba967314
--- /dev/null
+++ b/UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.c
@@ -0,0 +1,426 @@
+/** @file=0D
+ This driver will probe for the Option Rom and provide a pointer to=0D
+ the activated BAR if found.=0D
+=0D
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>=0D
+SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+=0D
+=0D
+**/=0D
+=0D
+#include "PciPlatformDxe.h"=0D
+#include <Bus/Pci/PciBusDxe/PciBus.h>=0D
+#include <Bus/Pci/PciBusDxe/PciOptionRomSupport.h>=0D
+=0D
+//=0D
+// The driver should only start on one graphics controller.=0D
+// So a global flag is used to remember that the driver is already started=
.=0D
+//=0D
+EFI_HANDLE mDriverHandle =3D NULL;=0D
+=0D
+/**=0D
+ The notification from the PCI bus enumerator to the platform that it is=
=0D
+ about to enter a certain phase during the enumeration process.=0D
+=0D
+ @param[in] This The pointer to the EFI_PCI_PLATFORM_PROTOCOL i=
nstance.=0D
+ @param[in] HostBridge The handle of the host bridge controller.=0D
+ @param[in] Phase The phase of the PCI bus enumeration.=0D
+ @param[in] ExecPhase Defines the execution phase of the PCI chipset=
driver.=0D
+=0D
+ @retval EFI_SUCCESS The function completed successfully.=0D
+=0D
+**/=0D
+EFI_STATUS=0D
+EFIAPI=0D
+PciPlatformNotify(=0D
+ IN EFI_PCI_PLATFORM_PROTOCOL *This,=0D
+ IN EFI_HANDLE HostBridge,=0D
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase,=0D
+ IN EFI_PCI_EXECUTION_PHASE ExecPhase=0D
+ )=0D
+{=0D
+ return EFI_SUCCESS;=0D
+}=0D
+=0D
+=0D
+/**=0D
+ The notification from the PCI bus enumerator to the platform for each PC=
I=0D
+ controller at several predefined points during PCI controller initializa=
tion.=0D
+=0D
+ @param[in] This The pointer to the EFI_PCI_PLATFORM_PROTOCOL i=
nstance.=0D
+ @param[in] HostBridge The associated PCI host bridge handle.=0D
+ @param[in] RootBridge The associated PCI root bridge handle.=0D
+ @param[in] PciAddress The address of the PCI device on the PCI bus.=
=0D
+ @param[in] Phase The phase of the PCI controller enumeration.=0D
+ @param[in] ExecPhase Defines the execution phase of the PCI chipset=
driver.=0D
+=0D
+ @retval EFI_SUCCESS The function completed successfully.=0D
+=0D
+**/=0D
+EFI_STATUS=0D
+EFIAPI=0D
+PciPlatformPrepController(=0D
+ IN EFI_PCI_PLATFORM_PROTOCOL *This,=0D
+ IN EFI_HANDLE HostBridge,=0D
+ IN EFI_HANDLE RootBridge,=0D
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress,=0D
+ IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase,=0D
+ IN EFI_PCI_EXECUTION_PHASE ExecPhase=0D
+ )=0D
+{=0D
+ return EFI_SUCCESS;=0D
+}=0D
+=0D
+/**=0D
+ Gets the PCI device's option ROM.=0D
+=0D
+ @param[in] This The pointer to the EFI_PCI_PLATFORM_PROTOCOL ins=
tance.=0D
+ @param[in] PciHandle The handle of the PCI device.=0D
+ @param[out] RomImage If the call succeeds, the pointer to the pointer=
to the option ROM image.=0D
+ Otherwise, this field is undefined. The memory f=
or RomImage is allocated=0D
+ by EFI_PCI_PLATFORM_PROTOCOL.GetPciRom() using t=
he EFI Boot Service AllocatePool().=0D
+ It is the caller's responsibility to free the me=
mory using the EFI Boot Service=0D
+ FreePool(), when the caller is done with the opt=
ion ROM.=0D
+ @param[out] RomSize If the call succeeds, a pointer to the size of t=
he option ROM size. Otherwise,=0D
+ this field is undefined.=0D
+=0D
+ @retval EFI_SUCCESS The option ROM was available for this dev=
ice and loaded into memory.=0D
+ @retval EFI_NOT_FOUND No option ROM was available for this devi=
ce.=0D
+ @retval EFI_OUT_OF_RESOURCES No memory was available to load the optio=
n ROM.=0D
+ @retval EFI_DEVICE_ERROR An error occurred in obtaining the option=
ROM.=0D
+=0D
+**/=0D
+EFI_STATUS=0D
+EFIAPI=0D
+PciGetPciRom (=0D
+ IN CONST EFI_PCI_PLATFORM_PROTOCOL *This,=0D
+ IN EFI_HANDLE PciHandle,=0D
+ OUT VOID **RomImage,=0D
+ OUT UINTN *RomSize=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ IN EFI_PCI_IO_PROTOCOL *PciIo;=0D
+ UINTN PciSegment;=0D
+ UINTN PciBus;=0D
+ UINTN PciDevice;=0D
+ UINTN PciFunction;=0D
+ UINTN RomBarIndex;=0D
+ UINT32 Buffer;=0D
+ UINT32 AllOnes;=0D
+ PCI_IO_DEVICE *PciIoDevice;=0D
+ UINT8 Indicator;=0D
+ UINT16 OffsetPcir;=0D
+ UINT32 RomBarOffset;=0D
+ UINT32 RomBar;=0D
+ BOOLEAN FirstCheck;=0D
+ PCI_EXPANSION_ROM_HEADER *RomHeader;=0D
+ PCI_DATA_STRUCTURE *RomPcir;=0D
+ UINT64 RomImageSize;=0D
+ UINT32 LegacyImageLength;=0D
+ UINT8 *RomInMemory;=0D
+ UINT8 CodeType;=0D
+=0D
+ if (!RomImage || !RomSize) {=0D
+ return EFI_INVALID_PARAMETER;=0D
+ }=0D
+=0D
+ *RomImage =3D NULL;=0D
+ *RomSize =3D 0;=0D
+=0D
+ Status =3D gBS->HandleProtocol (=0D
+ PciHandle,=0D
+ &gEfiPciIoProtocolGuid,=0D
+ (VOID **) &PciIo=0D
+ );=0D
+ if (EFI_ERROR (Status)) {=0D
+ DEBUG ((DEBUG_INFO, "%a: Failed to open gEfiPciIoProtocolGuid\n", __=
FUNCTION__));=0D
+=0D
+ return EFI_UNSUPPORTED;=0D
+ }=0D
+ PciIoDevice =3D PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);=0D
+=0D
+ //=0D
+ // Get the location of the PCI device=0D
+ //=0D
+ PciIo->GetLocation (=0D
+ PciIo,=0D
+ &PciSegment,=0D
+ &PciBus,=0D
+ &PciDevice,=0D
+ &PciFunction=0D
+ );=0D
+=0D
+ DEBUG ((DEBUG_INFO, "%a: Searching Option ROM on device:\n", __FUNCTION_=
_));=0D
+ DEBUG ((DEBUG_INFO, " PciSegment - %02x\n", PciSegment));=0D
+ DEBUG ((DEBUG_INFO, " PciBus - %02x\n", PciBus));=0D
+ DEBUG ((DEBUG_INFO, " PciDevice - %02x\n", PciDevice));=0D
+ DEBUG ((DEBUG_INFO, " PciFunction - %02x\n", PciFunction));=0D
+=0D
+ //=0D
+ // Offset is 0x30 if is not ppb=0D
+ //=0D
+ RomBarIndex =3D PCI_EXPANSION_ROM_BASE;=0D
+=0D
+ if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) {=0D
+ //=0D
+ // If is ppb, 0x38=0D
+ //=0D
+ RomBarIndex =3D PCI_BRIDGE_ROMBAR;=0D
+ }=0D
+=0D
+ //=0D
+ // Backup BAR=0D
+ //=0D
+ Status =3D PciIo->Pci.Read (=0D
+ PciIo,=0D
+ EfiPciWidthUint32,=0D
+ RomBarIndex,=0D
+ 1,=0D
+ &Buffer=0D
+ );=0D
+ if (EFI_ERROR (Status)) {=0D
+ goto CloseAndReturn;=0D
+ return Status;=0D
+ }=0D
+=0D
+ //=0D
+ // The bit0 is 0 to prevent the enabling of the Rom address decoder=0D
+ //=0D
+ AllOnes =3D 0xfffffffe;=0D
+=0D
+ Status =3D PciIo->Pci.Write (=0D
+ PciIo,=0D
+ EfiPciWidthUint32,=0D
+ RomBarIndex,=0D
+ 1,=0D
+ &AllOnes=0D
+ );=0D
+ if (EFI_ERROR (Status)) {=0D
+ goto CloseAndReturn;=0D
+ }=0D
+=0D
+ //=0D
+ // Read back=0D
+ //=0D
+ Status =3D PciIo->Pci.Read(=0D
+ PciIo,=0D
+ EfiPciWidthUint32,=0D
+ RomBarIndex,=0D
+ 1,=0D
+ &AllOnes=0D
+ );=0D
+ if (EFI_ERROR (Status)) {=0D
+ goto CloseAndReturn;=0D
+ }=0D
+=0D
+ //=0D
+ // Bits [1, 10] are reserved=0D
+ //=0D
+ AllOnes &=3D 0xFFFFF800;=0D
+ if ((AllOnes =3D=3D 0) || (AllOnes =3D=3D 0xFFFFF800)) {=0D
+ DEBUG ((DEBUG_INFO, "%a: No Option ROM found\n", __FUNCTION__));=0D
+ return EFI_NOT_FOUND;=0D
+ }=0D
+=0D
+ *RomSize =3D (~AllOnes) + 1;=0D
+=0D
+ DEBUG ((DEBUG_INFO, "%a: Option ROM with size %d\n", __FUNCTION__, *RomS=
ize));=0D
+=0D
+ //=0D
+ // Restore BAR and enable it=0D
+ //=0D
+ Buffer |=3D 1;=0D
+ Status =3D PciIo->Pci.Write (=0D
+ PciIo,=0D
+ EfiPciWidthUint32,=0D
+ RomBarIndex,=0D
+ 1,=0D
+ &Buffer=0D
+ );=0D
+ if (EFI_ERROR (Status)) {=0D
+ goto CloseAndReturn;=0D
+ }=0D
+=0D
+ //=0D
+ // Allocate memory for Rom header and PCIR=0D
+ //=0D
+ RomHeader =3D AllocatePool (sizeof (PCI_EXPANSION_ROM_HEADER));=0D
+ if (RomHeader =3D=3D NULL) {=0D
+ Status =3D EFI_OUT_OF_RESOURCES;=0D
+ goto CloseAndReturn;=0D
+ }=0D
+=0D
+ RomPcir =3D AllocatePool (sizeof (PCI_DATA_STRUCTURE));=0D
+ if (RomPcir =3D=3D NULL) {=0D
+ FreePool (RomHeader);=0D
+ Status =3D EFI_OUT_OF_RESOURCES;=0D
+ goto CloseAndReturn;=0D
+ }=0D
+=0D
+ // FIXME: Use gEfiPciRootBridgeIoProtocolGuid=0D
+ RomBar =3D (UINT32) Buffer &~1;=0D
+=0D
+ RomBarOffset =3D RomBar;=0D
+ FirstCheck =3D TRUE;=0D
+ LegacyImageLength =3D 0;=0D
+ RomImageSize =3D 0;=0D
+=0D
+ do {=0D
+ // FIXME: Use gEfiPciRootBridgeIoProtocolGuid=0D
+ CopyMem(RomHeader, (VOID *)(UINTN)RomBarOffset, sizeof (PCI_EXPANSION_=
ROM_HEADER));=0D
+=0D
+ DEBUG ((DEBUG_INFO, "%a: RomHeader->Signature %x\n", __FUNCTION__, Rom=
Header->Signature));=0D
+=0D
+ if (RomHeader->Signature !=3D PCI_EXPANSION_ROM_HEADER_SIGNATURE) {=0D
+=0D
+ RomBarOffset =3D RomBarOffset + 512;=0D
+ if (FirstCheck) {=0D
+ break;=0D
+ } else {=0D
+ RomImageSize =3D RomImageSize + 512;=0D
+ continue;=0D
+ }=0D
+ }=0D
+=0D
+ FirstCheck =3D FALSE;=0D
+ OffsetPcir =3D RomHeader->PcirOffset;=0D
+ //=0D
+ // If the pointer to the PCI Data Structure is invalid, no further ima=
ges can be located.=0D
+ // The PCI Data Structure must be DWORD aligned.=0D
+ //=0D
+ if (OffsetPcir =3D=3D 0 ||=0D
+ (OffsetPcir & 3) !=3D 0 ||=0D
+ RomImageSize + OffsetPcir + sizeof (PCI_DATA_STRUCTURE) > *RomSize=
) {=0D
+ break;=0D
+ }=0D
+ // FIXME: Use gEfiPciRootBridgeIoProtocolGuid=0D
+ CopyMem(RomPcir, (VOID *)(UINTN)RomBarOffset + OffsetPcir, sizeof (PCI=
_DATA_STRUCTURE));=0D
+=0D
+ DEBUG ((DEBUG_INFO, "%a: RomPcir->Signature %x\n", __FUNCTION__, RomPc=
ir->Signature));=0D
+=0D
+ //=0D
+ // If a valid signature is not present in the PCI Data Structure, no f=
urther images can be located.=0D
+ //=0D
+ if (RomPcir->Signature !=3D PCI_DATA_STRUCTURE_SIGNATURE) {=0D
+ break;=0D
+ }=0D
+ if (RomImageSize + RomPcir->ImageLength * 512 > *RomSize) {=0D
+ break;=0D
+ }=0D
+ if (RomPcir->CodeType =3D=3D PCI_CODE_TYPE_PCAT_IMAGE) {=0D
+ CodeType =3D PCI_CODE_TYPE_PCAT_IMAGE;=0D
+ LegacyImageLength =3D ((UINT32)((EFI_LEGACY_EXPANSION_ROM_HEADER *)R=
omHeader)->Size512) * 512;=0D
+ }=0D
+ Indicator =3D RomPcir->Indicator;=0D
+ RomImageSize =3D RomImageSize + RomPcir->ImageLength * 512;=0D
+ RomBarOffset =3D RomBarOffset + RomPcir->ImageLength * 512;=0D
+ } while (((Indicator & 0x80) =3D=3D 0x00) && ((RomBarOffset - RomBar) < =
*RomSize));=0D
+=0D
+ //=0D
+ // Some Legacy Cards do not report the correct ImageLength so used the m=
aximum=0D
+ // of the legacy length and the PCIR Image Length=0D
+ //=0D
+ if (CodeType =3D=3D PCI_CODE_TYPE_PCAT_IMAGE) {=0D
+ RomImageSize =3D MAX (RomImageSize, LegacyImageLength);=0D
+ }=0D
+=0D
+ if (RomImageSize > 0) {=0D
+ // FIXME: Use gEfiPciRootBridgeIoProtocolGuid=0D
+ RomInMemory =3D (VOID *)(UINTN)RomBar;=0D
+ }=0D
+=0D
+ //=0D
+ // Free allocated memory=0D
+ //=0D
+ FreePool (RomHeader);=0D
+ FreePool (RomPcir);=0D
+=0D
+ if (RomImageSize > 0) {=0D
+ *RomImage =3D RomInMemory;=0D
+ *RomSize =3D RomImageSize;=0D
+ DEBUG ((DEBUG_INFO, "%a: Found Option ROM at %p, length 0x%x\n", __FUN=
CTION__,=0D
+ RomInMemory, RomImageSize));=0D
+=0D
+ Status =3D EFI_SUCCESS;=0D
+ } else {=0D
+ Status =3D EFI_NOT_FOUND;=0D
+ }=0D
+=0D
+CloseAndReturn:=0D
+ //=0D
+ // Close the I/O Abstraction(s) used to perform the supported test=0D
+ //=0D
+ gBS->CloseProtocol (=0D
+ PciHandle,=0D
+ &gEfiPciIoProtocolGuid,=0D
+ PciIo,=0D
+ PciHandle=0D
+ );=0D
+=0D
+ return Status;=0D
+}=0D
+=0D
+/**=0D
+ Retrieves the platform policy regarding enumeration.=0D
+=0D
+ The GetPlatformPolicy() function retrieves the platform policy regarding=
PCI=0D
+ enumeration. The PCI bus driver and the PCI Host Bridge Resource Allocat=
ion Protocol=0D
+ driver can call this member function to retrieve the policy.=0D
+=0D
+ @param[in] This The pointer to the EFI_PCI_PLATFORM_PROTOCOL ins=
tance.=0D
+ @param[out] PciPolicy The platform policy with respect to VGA and ISA =
aliasing.=0D
+=0D
+ @retval EFI_SUCCESS The function completed successfully.=0D
+ @retval EFI_INVALID_PARAMETER PciPolicy is NULL.=0D
+=0D
+**/=0D
+EFI_STATUS=0D
+EFIAPI=0D
+PciGetPlatformPolicy (=0D
+ IN CONST EFI_PCI_PLATFORM_PROTOCOL *This,=0D
+ OUT EFI_PCI_PLATFORM_POLICY *PciPolicy=0D
+ )=0D
+{=0D
+ if (PciPolicy =3D=3D NULL)=0D
+ return EFI_INVALID_PARAMETER;=0D
+=0D
+ *PciPolicy =3D 0;=0D
+=0D
+ return EFI_SUCCESS;=0D
+}=0D
+=0D
+EFI_PCI_PLATFORM_PROTOCOL mPciPlatformProtocol =3D {=0D
+ PciPlatformNotify,=0D
+ PciPlatformPrepController,=0D
+ PciGetPlatformPolicy,=0D
+ PciGetPciRom,=0D
+};=0D
+=0D
+/**=0D
+ The Entry Point for Option ROM driver.=0D
+=0D
+ It installs DriverBinding.=0D
+=0D
+ @retval EFI_SUCCESS The entry point is executed successfully.=0D
+ @retval other Some error occurs when executing this entry po=
int.=0D
+=0D
+**/=0D
+EFI_STATUS=0D
+EFIAPI=0D
+InstallPciPlatformProtocol (=0D
+ IN EFI_HANDLE ImageHandle,=0D
+ IN EFI_SYSTEM_TABLE *SystemTable=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+=0D
+ Status =3D gBS->InstallProtocolInterface (=0D
+ &mDriverHandle,=0D
+ &gEfiPciPlatformProtocolGuid,=0D
+ EFI_NATIVE_INTERFACE,=0D
+ &mPciPlatformProtocol=0D
+ );=0D
+=0D
+ return Status;=0D
+}=0D
--=20
2.28.0


[PATCH v2 1/2] MdeModulePkg: Fix OptionROM scanning

Marcello Sylvester Bauer <marcello.bauer@...>
 

From: Patrick Rudolph <patrick.rudolph@9elements.com>

The Option ROM scanner can't work as enumeration was done by the
first stage bootloader. Running it will disable the ability of the
PCIPlatform code to scan for ROMs.

Required for the following patch that enables custom Option ROM
scanning using gPciPlatformProtocol.

Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Signed-off-by: Marcello Sylvester Bauer <marcello.bauer@9elements.com>
Cc: Patrick Rudolph <patrick.rudolph@9elements.com>
Cc: Christian Walter <christian.walter@9elements.com>
Cc: Hao A Wu <hao.a.wu@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
---
MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c b/MdeMod=
ulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
index 6c68a97d4e46..7420f0079f7d 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
@@ -2530,10 +2530,12 @@ PciEnumeratorLight (
//=0D
RemoveRejectedPciDevices (RootBridgeDev->Handle, RootBridgeDev);=0D
=0D
- //=0D
- // Process option rom light=0D
- //=0D
- ProcessOptionRomLight (RootBridgeDev);=0D
+ if (!PcdGetBool (PcdPciDisableBusEnumeration)) {=0D
+ //=0D
+ // Process option rom light=0D
+ //=0D
+ ProcessOptionRomLight (RootBridgeDev);=0D
+ }=0D
=0D
//=0D
// Determine attributes for all devices under this root bridge=0D
--=20
2.28.0


[PATCH v2 0/2] Add support for scanning Option ROMs

Marcello Sylvester Bauer <marcello.bauer@...>
 

Fix Option ROM enumeration and support scanning.

v2:
* add correct Maintainer and Reviewer to Cc
* PciPlatformDxe:
- Update description
- add function description

Branch: https://github.com/9elements/edk2-1/tree/UefiPayloadPkg-Option_ROMs
PR: https://github.com/tianocore/edk2/pull/926

Patrick Rudolph (2):
MdeModulePkg: Fix OptionROM scanning
UefiPayloadPkg: Scan for Option ROMs

UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 1 +
UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 1 +
UefiPayloadPkg/UefiPayloadPkg.fdf | 1 +
UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.inf | 46 +++
UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.h | 19 +
MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c | 10 +-
UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.c | 426 ++++++++++++++++++++
7 files changed, 500 insertions(+), 4 deletions(-)
create mode 100644 UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.inf
create mode 100644 UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.h
create mode 100644 UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.c

--
2.28.0


Re: [PATCH v1 1/1] Platform/RaspberryPi/ConfigDxe: Fix JTAG Pinout for Pi3/4

Pete Batard
 

Copying Andrei on this, as the existing JTAG pinout is not technically incorrect, since GPIO pin 4 can be used for TDI in ALT5 mode, and we are using the relevant ALT mode in the existing code. See https://sysprogs.com/VisualKernel/tutorials/raspberry/jtagsetup/

As far as I'm concerned, I think it makes sense to use the same ALT mode and have all the JTAG pins grouped, but I'd like to confirm whether we deliberately chose not to use GPIO 26 in order to leave it available for some other purpose, before I approve this patch.

If Andrei says he's okay with it, then I see no objection to this change.

Regards,

/Pete

On 2020.09.14 22:32, Jeff Booher-Kaeding wrote:
Updated the pinout to match the Pi4 datasheet, tested with the RPi4, Pi3 Datasheet has same pinout.
Signed-off-by: Jeff Booher-Kaeding <Jeff.booher-kaeding@arm.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Pete Batard <pete@akeo.ie>
---
Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.c b/Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.c
index ac1004fe1836..6e793efb8227 100644
--- a/Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.c
+++ b/Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.c
@@ -502,7 +502,7 @@ ApplyVariables (
* 1 VREF N/A 1
* 3 nTRST GPIO22 ALT4 15
* 4 GND N/A 9
- * 5 TDI GPIO4 ALT5 7
+ * 5 TDI GPIO26 ALT4 37
* 7 TMS GPIO27 ALT4 13
* 9 TCK GPIO25 ALT4 22
* 11 RTCK GPIO23 ALT4 16
@@ -510,14 +510,14 @@ ApplyVariables (
*/
if (PcdGet32 (PcdDebugEnableJTAG)) {
GpioPinFuncSet (22, GPIO_FSEL_ALT4);
- GpioPinFuncSet (4, GPIO_FSEL_ALT5);
+ GpioPinFuncSet (26, GPIO_FSEL_ALT4);
GpioPinFuncSet (27, GPIO_FSEL_ALT4);
GpioPinFuncSet (25, GPIO_FSEL_ALT4);
GpioPinFuncSet (23, GPIO_FSEL_ALT4);
GpioPinFuncSet (24, GPIO_FSEL_ALT4);
} else {
GpioPinFuncSet (22, GPIO_FSEL_INPUT);
- GpioPinFuncSet (4, GPIO_FSEL_INPUT);
+ GpioPinFuncSet (26, GPIO_FSEL_INPUT);
GpioPinFuncSet (27, GPIO_FSEL_INPUT);
GpioPinFuncSet (25, GPIO_FSEL_INPUT);
GpioPinFuncSet (23, GPIO_FSEL_INPUT);


[edk2-platforms 3/4] Silicon/NXP: Implement USB Errata

Meenakshi Aggarwal <meenakshi.aggarwal@...>
 

Implement USB errata A009008, A009798, A008997, A009007
Make USB,SEC and SATA snoopable

Signed-off-by: Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>
---
Silicon/NXP/NxpQoriqLs.dec | 1 +
Silicon/NXP/LS1046A/LS1046A.dsc.inc | 1 +
.../NXP/Chassis2/Library/ChassisLib/ChassisLib.inf | 2 +
Silicon/NXP/LS1046A/Library/SocLib/SocLib.inf | 2 +
Silicon/NXP/Chassis2/Include/Chassis.h | 112 +++++++++++++++
Silicon/NXP/Chassis2/Library/ChassisLib/Erratum.h | 23 +++
Silicon/NXP/Include/Library/ChassisLib.h | 62 ++++++++
Silicon/NXP/LS1046A/Include/Soc.h | 2 +
.../NXP/Chassis2/Library/ChassisLib/ChassisLib.c | 63 ++++++++
Silicon/NXP/Chassis2/Library/ChassisLib/Erratum.c | 159 +++++++++++++++++++++
Silicon/NXP/LS1046A/Library/SocLib/SocLib.c | 66 +++++++++
11 files changed, 493 insertions(+)
create mode 100644 Silicon/NXP/Chassis2/Library/ChassisLib/Erratum.h
create mode 100644 Silicon/NXP/Chassis2/Library/ChassisLib/Erratum.c

diff --git a/Silicon/NXP/NxpQoriqLs.dec b/Silicon/NXP/NxpQoriqLs.dec
index 3a568c0437e7..90dce69fd472 100644
--- a/Silicon/NXP/NxpQoriqLs.dec
+++ b/Silicon/NXP/NxpQoriqLs.dec
@@ -30,6 +30,7 @@ [PcdsFeatureFlag]
gNxpQoriqLsTokenSpaceGuid.PcdPciLutBigEndian|FALSE|BOOLEAN|0x00000317
gNxpQoriqLsTokenSpaceGuid.PcdSataErratumA009185|FALSE|BOOLEAN|0x00000318
gNxpQoriqLsTokenSpaceGuid.PcdGpioControllerBigEndian|FALSE|BOOLEAN|0x00000319
+ gNxpQoriqLsTokenSpaceGuid.PcdScfgBigEndian|FALSE|BOOLEAN|0x00000320

[PcdsFixedAtBuild.common]
# Pcds for PCI Express
diff --git a/Silicon/NXP/LS1046A/LS1046A.dsc.inc b/Silicon/NXP/LS1046A/LS1046A.dsc.inc
index db110553605f..4e1d6a7ae7a2 100644
--- a/Silicon/NXP/LS1046A/LS1046A.dsc.inc
+++ b/Silicon/NXP/LS1046A/LS1046A.dsc.inc
@@ -34,6 +34,7 @@ [PcdsFixedAtBuild.common]

[PcdsFeatureFlag]
gNxpQoriqLsTokenSpaceGuid.PcdDcfgBigEndian|TRUE
+ gNxpQoriqLsTokenSpaceGuid.PcdScfgBigEndian|TRUE
gNxpQoriqLsTokenSpaceGuid.PcdGpioControllerBigEndian|TRUE

################################################################################
diff --git a/Silicon/NXP/Chassis2/Library/ChassisLib/ChassisLib.inf b/Silicon/NXP/Chassis2/Library/ChassisLib/ChassisLib.inf
index f5dbd1349dc5..d64286b199c6 100644
--- a/Silicon/NXP/Chassis2/Library/ChassisLib/ChassisLib.inf
+++ b/Silicon/NXP/Chassis2/Library/ChassisLib/ChassisLib.inf
@@ -28,6 +28,8 @@ [LibraryClasses]

[Sources.common]
ChassisLib.c
+ Erratum.c

[FeaturePcd]
gNxpQoriqLsTokenSpaceGuid.PcdDcfgBigEndian
+ gNxpQoriqLsTokenSpaceGuid.PcdScfgBigEndian
diff --git a/Silicon/NXP/LS1046A/Library/SocLib/SocLib.inf b/Silicon/NXP/LS1046A/Library/SocLib/SocLib.inf
index 01ed0f6592d2..e2336bb18f29 100644
--- a/Silicon/NXP/LS1046A/Library/SocLib/SocLib.inf
+++ b/Silicon/NXP/LS1046A/Library/SocLib/SocLib.inf
@@ -14,6 +14,7 @@ [Defines]
LIBRARY_CLASS = SocLib

[Packages]
+ ArmPkg/ArmPkg.dec
MdePkg/MdePkg.dec
Silicon/NXP/Chassis2/Chassis2.dec
Silicon/NXP/LS1046A/LS1046A.dec
@@ -25,3 +26,4 @@ [LibraryClasses]

[Sources.common]
SocLib.c
+
diff --git a/Silicon/NXP/Chassis2/Include/Chassis.h b/Silicon/NXP/Chassis2/Include/Chassis.h
index 7e8bf224884b..f8fa7ed67596 100644
--- a/Silicon/NXP/Chassis2/Include/Chassis.h
+++ b/Silicon/NXP/Chassis2/Include/Chassis.h
@@ -11,6 +11,7 @@
#include <Uefi.h>

#define NXP_LAYERSCAPE_CHASSIS2_DCFG_ADDRESS 0x1EE0000
+#define NXP_LAYERSCAPE_CHASSIS2_SCFG_ADDRESS 0x1570000

#define SVR_SOC_VER(svr) (((svr) >> 8) & 0xFFFFFE)
#define SVR_MAJOR(svr) (((svr) >> 4) & 0xf)
@@ -26,6 +27,10 @@
#define SCR0_CLIENTPD_MASK 0x00000001
#define SACR_PAGESIZE_MASK 0x00010000

+#define USB_PHY1_BASE_ADDRESS 0x084F0000
+#define USB_PHY2_BASE_ADDRESS 0x08500000
+#define USB_PHY3_BASE_ADDRESS 0x08510000
+
/**
The Device Configuration Unit provides general purpose configuration and
status for the device. These registers only support 32-bit accesses.
@@ -45,4 +50,111 @@ typedef struct {
} NXP_LAYERSCAPE_CHASSIS2_DEVICE_CONFIG;
#pragma pack()

+/* Supplemental Configuration Unit (SCFG) */
+typedef struct {
+ UINT8 Res000[0x070-0x000];
+ UINT32 Usb1Prm1Cr;
+ UINT32 Usb1Prm2Cr;
+ UINT32 Usb1Prm3Cr;
+ UINT32 Usb2Prm1Cr;
+ UINT32 Usb2Prm2Cr;
+ UINT32 Usb2Prm3Cr;
+ UINT32 Usb3Prm1Cr;
+ UINT32 Usb3Prm2Cr;
+ UINT32 Usb3Prm3Cr;
+ UINT8 Res094[0x100-0x094];
+ UINT32 Usb2Icid;
+ UINT32 Usb3Icid;
+ UINT8 Res108[0x114-0x108];
+ UINT32 DmaIcid;
+ UINT32 SataIcid;
+ UINT32 Usb1Icid;
+ UINT32 QeIcid;
+ UINT32 SdhcIcid;
+ UINT32 EdmaIcid;
+ UINT32 EtrIcid;
+ UINT32 Core0SftRst;
+ UINT32 Core1SftRst;
+ UINT32 Core2SftRst;
+ UINT32 Core3SftRst;
+ UINT8 Res140[0x158-0x140];
+ UINT32 AltCBar;
+ UINT32 QspiCfg;
+ UINT8 Res160[0x180-0x160];
+ UINT32 DmaMcr;
+ UINT8 Res184[0x188-0x184];
+ UINT32 GicAlign;
+ UINT32 DebugIcid;
+ UINT8 Res190[0x1a4-0x190];
+ UINT32 SnpCnfgCr;
+#define SCFG_SNPCNFGCR_SECRDSNP BIT31
+#define SCFG_SNPCNFGCR_SECWRSNP BIT30
+#define SCFG_SNPCNFGCR_SATARDSNP BIT23
+#define SCFG_SNPCNFGCR_SATAWRSNP BIT22
+#define SCFG_SNPCNFGCR_USB1RDSNP BIT21
+#define SCFG_SNPCNFGCR_USB1WRSNP BIT20
+#define SCFG_SNPCNFGCR_USB2RDSNP BIT15
+#define SCFG_SNPCNFGCR_USB2WRSNP BIT16
+#define SCFG_SNPCNFGCR_USB3RDSNP BIT13
+#define SCFG_SNPCNFGCR_USB3WRSNP BIT14
+ UINT8 Res1a8[0x1ac-0x1a8];
+ UINT32 IntpCr;
+ UINT8 Res1b0[0x204-0x1b0];
+ UINT32 CoreSrEnCr;
+ UINT8 Res208[0x220-0x208];
+ UINT32 RvBar00;
+ UINT32 RvBar01;
+ UINT32 RvBar10;
+ UINT32 RvBar11;
+ UINT32 RvBar20;
+ UINT32 RvBar21;
+ UINT32 RvBar30;
+ UINT32 RvBar31;
+ UINT32 LpmCsr;
+ UINT8 Res244[0x400-0x244];
+ UINT32 QspIdQScr;
+ UINT32 EcgTxcMcr;
+ UINT32 SdhcIoVSelCr;
+ UINT32 RcwPMuxCr0;
+ /**Setting RCW PinMux Register bits 17-19 to select USB2_DRVVBUS
+ Setting RCW PinMux Register bits 21-23 to select USB2_PWRFAULT
+ Setting RCW PinMux Register bits 25-27 to select USB3_DRVVBUS
+ Setting RCW PinMux Register bits 29-31 to select USB3_DRVVBUS
+ **/
+#define SCFG_RCWPMUXCRO_SELCR_USB 0x3333
+ /**Setting RCW PinMux Register bits 17-19 to select USB2_DRVVBUS
+ Setting RCW PinMux Register bits 21-23 to select USB2_PWRFAULT
+ Setting RCW PinMux Register bits 25-27 to select IIC4_SCL
+ Setting RCW PinMux Register bits 29-31 to select IIC4_SDA
+ **/
+#define SCFG_RCWPMUXCRO_NOT_SELCR_USB 0x3300
+ UINT32 UsbDrvVBusSelCr;
+#define SCFG_USBDRVVBUS_SELCR_USB1 0x00000000
+#define SCFG_USBDRVVBUS_SELCR_USB2 0x00000001
+#define SCFG_USBDRVVBUS_SELCR_USB3 0x00000003
+ UINT32 UsbPwrFaultSelCr;
+#define SCFG_USBPWRFAULT_INACTIVE 0x00000000
+#define SCFG_USBPWRFAULT_SHARED 0x00000001
+#define SCFG_USBPWRFAULT_DEDICATED 0x00000002
+#define SCFG_USBPWRFAULT_USB3_SHIFT 4
+#define SCFG_USBPWRFAULT_USB2_SHIFT 2
+#define SCFG_USBPWRFAULT_USB1_SHIFT 0
+ UINT32 UsbRefclkSelcr1;
+ UINT32 UsbRefclkSelcr2;
+ UINT32 UsbRefclkSelcr3;
+ UINT8 Res424[0x600-0x424];
+ UINT32 ScratchRw[4];
+ UINT8 Res610[0x680-0x610];
+ UINT32 CoreBCr;
+ UINT8 Res684[0x1000-0x684];
+ UINT32 Pex1MsiIr;
+ UINT32 Pex1MsiR;
+ UINT8 Res1008[0x2000-0x1008];
+ UINT32 Pex2;
+ UINT32 Pex2MsiR;
+ UINT8 Res2008[0x3000-0x2008];
+ UINT32 Pex3MsiIr;
+ UINT32 Pex3MsiR;
+} NXP_LAYERSCAPE_CHASSIS2_SUPPLEMENTAL_CONFIG;
+
#endif // CHASSIS_H__
diff --git a/Silicon/NXP/Chassis2/Library/ChassisLib/Erratum.h b/Silicon/NXP/Chassis2/Library/ChassisLib/Erratum.h
new file mode 100644
index 000000000000..0231ef0a283d
--- /dev/null
+++ b/Silicon/NXP/Chassis2/Library/ChassisLib/Erratum.h
@@ -0,0 +1,23 @@
+/** @file
+* Header defining the Base addresses, sizes, flags etc for Erratas
+*
+* Copyright 2020 NXP
+*
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#ifndef ERRATUM_H__
+#define ERRATUM_H__
+
+#define USB_TXVREFTUNE 0x9
+#define USB_SQRXTUNE 0xFC7FFFFF
+#define USB_PCSTXSWINGFULL 0x47
+#define USB_PHY_RX_EQ_VAL_1 0x0000
+#define USB_PHY_RX_EQ_VAL_2 0x8000
+#define USB_PHY_RX_EQ_VAL_3 0x8003
+#define USB_PHY_RX_EQ_VAL_4 0x800b
+
+#define USB_PHY_RX_OVRD_IN_HI 0x200c
+
+#endif
diff --git a/Silicon/NXP/Include/Library/ChassisLib.h b/Silicon/NXP/Include/Library/ChassisLib.h
index 89992a4b6fd5..c99368b4733d 100644
--- a/Silicon/NXP/Include/Library/ChassisLib.h
+++ b/Silicon/NXP/Include/Library/ChassisLib.h
@@ -13,6 +13,48 @@
#include <Chassis.h>

/**
+ Or Scfg register
+
+ @param Address The MMIO register to read.
+
+ @return The value read.
+**/
+UINT32
+EFIAPI
+ScfgOr32 (
+ IN UINTN Address,
+ IN UINT32 Value
+ );
+
+/**
+ Read Scfg register
+
+ @param Address The MMIO register to read.
+
+ @return The value read.
+**/
+UINT32
+EFIAPI
+ScfgRead32 (
+ IN UINTN Address
+ );
+
+/**
+ Write Scfg register
+
+ @param Address The MMIO register to write.
+ @param Value The value to write to the MMIO register.
+
+ @return Value.
+**/
+UINT32
+EFIAPI
+ScfgWrite32 (
+ IN UINTN Address,
+ IN UINT32 Value
+ );
+
+/**
Read Dcfg register

@param Address The MMIO register to read.
@@ -48,4 +90,24 @@ ChassisInit (
VOID
);

+VOID
+ErratumA009008 (
+ VOID
+ );
+
+VOID
+ErratumA009798 (
+ VOID
+ );
+
+VOID
+ErratumA008997 (
+ VOID
+ );
+
+VOID
+ErratumA009007 (
+ VOID
+ );
+
#endif // CHASSIS_LIB_H__
diff --git a/Silicon/NXP/LS1046A/Include/Soc.h b/Silicon/NXP/LS1046A/Include/Soc.h
index 84f433d5cb94..e1d97e531263 100644
--- a/Silicon/NXP/LS1046A/Include/Soc.h
+++ b/Silicon/NXP/LS1046A/Include/Soc.h
@@ -25,6 +25,7 @@
#define LS1046A_QSPI0_SIZE (SIZE_512MB)

#define LS1046A_DCFG_ADDRESS NXP_LAYERSCAPE_CHASSIS2_DCFG_ADDRESS
+#define LS1046A_SCFG_ADDRESS NXP_LAYERSCAPE_CHASSIS2_SCFG_ADDRESS

/**
Reset Control Word (RCW) Bits
@@ -59,5 +60,6 @@ Bit(s) | Field Name | Description | Notes/comments
#define SYS_PLL_RAT(x) (((x) >> 25) & 0x1f) // Bits 2-6

typedef NXP_LAYERSCAPE_CHASSIS2_DEVICE_CONFIG LS1046A_DEVICE_CONFIG;
+typedef NXP_LAYERSCAPE_CHASSIS2_SUPPLEMENTAL_CONFIG LS1046A_SUPPLEMENTAL_CONFIG;

#endif // SOC_H__
diff --git a/Silicon/NXP/Chassis2/Library/ChassisLib/ChassisLib.c b/Silicon/NXP/Chassis2/Library/ChassisLib/ChassisLib.c
index 91b19f832f00..e6410a53f480 100644
--- a/Silicon/NXP/Chassis2/Library/ChassisLib/ChassisLib.c
+++ b/Silicon/NXP/Chassis2/Library/ChassisLib/ChassisLib.c
@@ -15,6 +15,69 @@
#include <Library/SerialPortLib.h>

/**
+ Or Scfg register
+
+ @param Address The MMIO register to read.
+
+ @return The value read.
+**/
+UINT32
+EFIAPI
+ScfgOr32 (
+ IN UINTN Address,
+ IN UINT32 Value
+ )
+{
+ MMIO_OPERATIONS *ScfgOps;
+
+ ScfgOps = GetMmioOperations (FeaturePcdGet (PcdScfgBigEndian));
+
+ return ScfgOps->Or32 (Address, Value);
+}
+
+/**
+ Read Scfg register
+
+ @param Address The MMIO register to read.
+
+ @return The value read.
+**/
+UINT32
+EFIAPI
+ScfgRead32 (
+ IN UINTN Address
+ )
+{
+ MMIO_OPERATIONS *ScfgOps;
+
+ ScfgOps = GetMmioOperations (FeaturePcdGet (PcdScfgBigEndian));
+
+ return ScfgOps->Read32 (Address);
+}
+
+/**
+ Write Scfg register
+
+ @param Address The MMIO register to write.
+ @param Value The value to write to the MMIO register.
+
+ @return Value.
+**/
+UINT32
+EFIAPI
+ScfgWrite32 (
+ IN UINTN Address,
+ IN UINT32 Value
+ )
+{
+ MMIO_OPERATIONS *ScfgOps;
+
+ ScfgOps = GetMmioOperations (FeaturePcdGet (PcdScfgBigEndian));
+
+ return ScfgOps->Write32 (Address, Value);
+}
+
+/**
Read Dcfg register

@param Address The MMIO register to read.
diff --git a/Silicon/NXP/Chassis2/Library/ChassisLib/Erratum.c b/Silicon/NXP/Chassis2/Library/ChassisLib/Erratum.c
new file mode 100644
index 000000000000..1806975ec8f5
--- /dev/null
+++ b/Silicon/NXP/Chassis2/Library/ChassisLib/Erratum.c
@@ -0,0 +1,159 @@
+/** @file
+ This file containa all erratas need to be applied on different SoCs.
+
+ Copyright 2020 NXP
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include <Library/ArmLib.h>
+#include <Library/BaseLib.h>
+#include <Library/ChassisLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+
+#include "Erratum.h"
+
+/*
+* A-009008: USB High Speed (HS) eye height adjustment
+* Affects: USB
+* Description: USB HS eye diagram fails with the default value at many corners, particularly at a high
+* temperature (105°C).
+* Impact: USB HS eye diagram may fail using the default value.
+*/
+VOID
+ErratumA009008 (
+ VOID
+ )
+{
+ NXP_LAYERSCAPE_CHASSIS2_SUPPLEMENTAL_CONFIG *Scfg;
+ UINT32 Value;
+
+ Scfg = (NXP_LAYERSCAPE_CHASSIS2_SUPPLEMENTAL_CONFIG *)NXP_LAYERSCAPE_CHASSIS2_SCFG_ADDRESS;
+
+ Value = ScfgRead32 ((UINTN)&Scfg->Usb1Prm1Cr);
+ Value &= ~(0xF << 6);
+ ScfgWrite32 ((UINTN)&Scfg->Usb1Prm1Cr, Value|(USB_TXVREFTUNE << 6));
+ Value = ScfgRead32 ((UINTN)&Scfg->Usb2Prm1Cr);
+ Value &= ~(0xF << 6);
+ ScfgWrite32 ((UINTN)&Scfg->Usb2Prm1Cr, Value|(USB_TXVREFTUNE << 6));
+ Value = ScfgRead32 ((UINTN)&Scfg->Usb3Prm1Cr);
+ Value &= ~(0xF << 6);
+ ScfgWrite32 ((UINTN)&Scfg->Usb3Prm1Cr, Value|(USB_TXVREFTUNE << 6));
+
+ return;
+}
+
+/*
+* A-009798: USB high speed squelch threshold adjustment
+* Affects: USB
+* Description: The default setting for USB high speed squelch threshold results in a threshold close to or
+* lower than 100mV. This leads to a receiver compliance test failure for a 100mV threshold.
+* Impact: If the errata is not applied, only the USB high speed receiver sensitivity compliance test fails,
+* however USB data continues to transfer.
+*/
+VOID
+ErratumA009798 (
+ VOID
+ )
+{
+ NXP_LAYERSCAPE_CHASSIS2_SUPPLEMENTAL_CONFIG *Scfg;
+ UINT32 Value;
+
+ Scfg = (NXP_LAYERSCAPE_CHASSIS2_SUPPLEMENTAL_CONFIG *)NXP_LAYERSCAPE_CHASSIS2_SCFG_ADDRESS;
+
+ Value = ScfgRead32 ((UINTN)&Scfg->Usb1Prm1Cr);
+ ScfgWrite32 ((UINTN)&Scfg->Usb1Prm1Cr, Value & USB_SQRXTUNE);
+ Value = ScfgRead32 ((UINTN)&Scfg->Usb2Prm1Cr);
+ ScfgWrite32 ((UINTN)&Scfg->Usb2Prm1Cr, Value & USB_SQRXTUNE);
+ Value = ScfgRead32 ((UINTN)&Scfg->Usb3Prm1Cr);
+ ScfgWrite32 ((UINTN)&Scfg->Usb3Prm1Cr, Value & USB_SQRXTUNE);
+
+ return;
+}
+
+/*
+* A-008997: USB3 LFPS peak-to-peak differential output voltage adjustment settings
+* Affects: USB
+* Description: Low Frequency Periodic Signaling (LFPS) peak-to-peak differential output voltage test
+* compliance fails using default transmitter settings. Software is required to change the
+* transmitter signal swings to pass compliance tests.
+* Impact: LFPS peak-to-peak differential output voltage compliance test fails.
+*/
+VOID
+ErratumA008997 (
+ VOID
+ )
+{
+ NXP_LAYERSCAPE_CHASSIS2_SUPPLEMENTAL_CONFIG *Scfg;
+ UINT32 Value;
+
+ Scfg = (NXP_LAYERSCAPE_CHASSIS2_SUPPLEMENTAL_CONFIG *)NXP_LAYERSCAPE_CHASSIS2_SCFG_ADDRESS;
+
+ Value = ScfgRead32 ((UINTN)&Scfg->Usb1Prm2Cr);
+ Value &= ~(0x7F << 9);
+ ScfgWrite32 ((UINTN)&Scfg->Usb1Prm2Cr, Value | (USB_PCSTXSWINGFULL << 9));
+ Value = ScfgRead32 ((UINTN)&Scfg->Usb2Prm2Cr);
+ Value &= ~(0x7F << 9);
+ ScfgWrite32 ((UINTN)&Scfg->Usb2Prm2Cr, Value | (USB_PCSTXSWINGFULL << 9));
+ Value = ScfgRead32 ((UINTN)&Scfg->Usb3Prm2Cr);
+ Value &= ~(0x7F << 9);
+ ScfgWrite32 ((UINTN)&Scfg->Usb3Prm2Cr, Value | (USB_PCSTXSWINGFULL << 9));
+
+ return;
+}
+
+/*
+* A-009007: USB3PHY observing intermittent failure in receive compliance tests
+* at higher jitter frequency using default register values
+*
+* Affects: USB
+*
+* Description: Receive compliance tests may fail intermittently at high jitter
+* frequencies using default register values.
+*
+* Impact: Receive compliance test fails at default register setting.
+*/
+
+VOID
+ConfigUsbLane0 (
+ IN UINTN UsbPhy
+ )
+{
+ UINTN RegAddress;
+
+ RegAddress = UsbPhy + USB_PHY_RX_OVRD_IN_HI;
+
+ ArmDataMemoryBarrier ();
+ MmioWrite16 (RegAddress, USB_PHY_RX_EQ_VAL_1);
+ ArmDataMemoryBarrier ();
+ MmioWrite16 (RegAddress, USB_PHY_RX_EQ_VAL_2);
+ ArmDataMemoryBarrier ();
+ MmioWrite16 (RegAddress, USB_PHY_RX_EQ_VAL_3);
+ ArmDataMemoryBarrier ();
+ MmioWrite16 (RegAddress, USB_PHY_RX_EQ_VAL_4);
+
+ return;
+}
+
+VOID
+ErratumA009007 (
+ VOID
+ )
+{
+ UINTN UsbPhy;
+
+ UsbPhy = USB_PHY1_BASE_ADDRESS;
+ ConfigUsbLane0 (UsbPhy);
+
+ UsbPhy = USB_PHY2_BASE_ADDRESS;
+ ConfigUsbLane0 (UsbPhy);
+
+ UsbPhy = USB_PHY3_BASE_ADDRESS;
+ ConfigUsbLane0 (UsbPhy);
+
+ return;
+}
diff --git a/Silicon/NXP/LS1046A/Library/SocLib/SocLib.c b/Silicon/NXP/LS1046A/Library/SocLib/SocLib.c
index 3b15aee6ecae..80342d7230e4 100644
--- a/Silicon/NXP/LS1046A/Library/SocLib/SocLib.c
+++ b/Silicon/NXP/LS1046A/Library/SocLib/SocLib.c
@@ -11,6 +11,8 @@
#include <Library/ChassisLib.h>
#include <Library/DebugLib.h>
#include <Library/SocLib.h>
+
+#include <Library/SocLib.h>
#include <Soc.h>

/**
@@ -65,6 +67,47 @@ SocGetClock (
}

/**
+ Function to select pins depending upon pcd using supplemental
+ configuration unit(SCFG) extended RCW controlled pinmux control
+ register which contains the bits to provide pin multiplexing control.
+ This register is reset on HRESET.
+ **/
+STATIC
+VOID
+ConfigScfgMux (VOID)
+{
+ LS1046A_SUPPLEMENTAL_CONFIG *Scfg;
+ UINT32 UsbPwrFault;
+
+ Scfg = (LS1046A_SUPPLEMENTAL_CONFIG *)LS1046A_SCFG_ADDRESS;
+ // Configures functionality of the IIC3_SCL to USB2_DRVVBUS
+ // Configures functionality of the IIC3_SDA to USB2_PWRFAULT
+ // USB3 is not used, configure mux to IIC4_SCL/IIC4_SDA
+ ScfgWrite32 ((UINTN)&Scfg->RcwPMuxCr0, SCFG_RCWPMUXCRO_NOT_SELCR_USB);
+
+ ScfgWrite32 ((UINTN)&Scfg->UsbDrvVBusSelCr, SCFG_USBDRVVBUS_SELCR_USB1);
+ UsbPwrFault = (SCFG_USBPWRFAULT_DEDICATED << SCFG_USBPWRFAULT_USB3_SHIFT) |
+ (SCFG_USBPWRFAULT_DEDICATED << SCFG_USBPWRFAULT_USB2_SHIFT) |
+ (SCFG_USBPWRFAULT_SHARED << SCFG_USBPWRFAULT_USB1_SHIFT);
+ ScfgWrite32 ((UINTN)&Scfg->UsbPwrFaultSelCr, UsbPwrFault);
+ ScfgWrite32 ((UINTN)&Scfg->UsbPwrFaultSelCr, UsbPwrFault);
+}
+
+STATIC
+VOID
+ApplyErrata (
+ VOID
+ )
+{
+ ErratumA009008 ();
+ ErratumA009798 ();
+ ErratumA008997 ();
+ ErratumA009007 ();
+}
+
+
+
+/**
Function to initialize SoC specific constructs
**/
VOID
@@ -72,7 +115,30 @@ SocInit (
VOID
)
{
+ LS1046A_SUPPLEMENTAL_CONFIG *Scfg;
+
+ Scfg = (LS1046A_SUPPLEMENTAL_CONFIG *)LS1046A_SCFG_ADDRESS;
+
+ /* Make SEC, SATA and USB reads and writes snoopable */
+ ScfgOr32((UINTN)&Scfg->SnpCnfgCr, SCFG_SNPCNFGCR_SECRDSNP |
+ SCFG_SNPCNFGCR_SECWRSNP | SCFG_SNPCNFGCR_USB1RDSNP |
+ SCFG_SNPCNFGCR_USB1WRSNP | SCFG_SNPCNFGCR_USB2RDSNP |
+ SCFG_SNPCNFGCR_USB2WRSNP | SCFG_SNPCNFGCR_USB3RDSNP |
+ SCFG_SNPCNFGCR_USB3WRSNP | SCFG_SNPCNFGCR_SATARDSNP |
+ SCFG_SNPCNFGCR_SATAWRSNP);
+
+ ApplyErrata ();
ChassisInit ();

+ //
+ // Due to the extensive functionality present on the chip and the limited number of external
+ // signals available, several functional blocks share signal resources through multiplexing.
+ // In this case when there is alternate functionality between multiple functional blocks,
+ // the signal's function is determined at the chip level (rather than at the block level)
+ // typically by a reset configuration word (RCW) option. Some of the signals' function are
+ // determined externel to RCW at Power-on Reset Sequence.
+ //
+ ConfigScfgMux ();
+
return;
}
--
1.9.1


[edk2-platforms 4/4] LS1046aFrwy: Enable USB support for LS1046AFRWY board.

Meenakshi Aggarwal <meenakshi.aggarwal@...>
 

Signed-off-by: Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>
---
Silicon/NXP/LS1046A/LS1046A.dsc.inc | 3 +++
Platform/NXP/LS1046aFrwyPkg/LS1046aFrwyPkg.dsc | 2 ++
Platform/NXP/LS1046aFrwyPkg/LS1046aFrwyPkg.fdf | 13 +++++++++++++
3 files changed, 18 insertions(+)
mode change 100644 => 100755 Platform/NXP/LS1046aFrwyPkg/LS1046aFrwyPkg.dsc
mode change 100644 => 100755 Platform/NXP/LS1046aFrwyPkg/LS1046aFrwyPkg.fdf

diff --git a/Silicon/NXP/LS1046A/LS1046A.dsc.inc b/Silicon/NXP/LS1046A/LS1046A.dsc.inc
index 4e1d6a7ae7a2..7004533ed5f1 100644
--- a/Silicon/NXP/LS1046A/LS1046A.dsc.inc
+++ b/Silicon/NXP/LS1046A/LS1046A.dsc.inc
@@ -31,6 +31,9 @@ [PcdsFixedAtBuild.common]
gNxpQoriqLsTokenSpaceGuid.PcdGpioModuleBaseAddress|0x02300000
gNxpQoriqLsTokenSpaceGuid.PcdGpioControllerOffset|0x10000

+ gNxpQoriqLsTokenSpaceGuid.PcdUsbBaseAddr|0x2F00000
+ gNxpQoriqLsTokenSpaceGuid.PcdUsbSize|0x100000
+ gNxpQoriqLsTokenSpaceGuid.PcdNumUsbController|3

[PcdsFeatureFlag]
gNxpQoriqLsTokenSpaceGuid.PcdDcfgBigEndian|TRUE
diff --git a/Platform/NXP/LS1046aFrwyPkg/LS1046aFrwyPkg.dsc b/Platform/NXP/LS1046aFrwyPkg/LS1046aFrwyPkg.dsc
old mode 100644
new mode 100755
index 3f29dadd5d1d..266fdbd2b4d3
--- a/Platform/NXP/LS1046aFrwyPkg/LS1046aFrwyPkg.dsc
+++ b/Platform/NXP/LS1046aFrwyPkg/LS1046aFrwyPkg.dsc
@@ -43,4 +43,6 @@ [Components.common]
gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable|TRUE
}

+ Silicon/NXP/Drivers/UsbHcdInitDxe/UsbHcd.inf
+
##
diff --git a/Platform/NXP/LS1046aFrwyPkg/LS1046aFrwyPkg.fdf b/Platform/NXP/LS1046aFrwyPkg/LS1046aFrwyPkg.fdf
old mode 100644
new mode 100755
index 24af547729c7..34c4e5a02516
--- a/Platform/NXP/LS1046aFrwyPkg/LS1046aFrwyPkg.fdf
+++ b/Platform/NXP/LS1046aFrwyPkg/LS1046aFrwyPkg.fdf
@@ -120,6 +120,19 @@ [FV.FvMain]
INF FatPkg/EnhancedFatDxe/Fat.inf
INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf

+ INF MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceDxe.inf
+
+ #
+ # USB Support
+ #
+ INF MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
+ INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+ INF MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
+ INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+ INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+ INF Silicon/NXP/Drivers/UsbHcdInitDxe/UsbHcd.inf
+
#
# UEFI application (Shell Embedded Boot Loader)
#
--
1.9.1


[edk2-platforms 2/4] Platform/NXP/LS1046aFrwyPkg: GPIO mux changes for USB

Meenakshi Aggarwal <meenakshi.aggarwal@...>
 

Signed-off-by: Pramod Kumar <pramod.kumar_1@nxp.com>
Signed-off-by: Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>
---
Silicon/NXP/NxpQoriqLs.dec | 8 ++++++++
Silicon/NXP/LS1046A/LS1046A.dsc.inc | 5 +++++
Silicon/NXP/NxpQoriqLs.dsc.inc | 2 ++
.../Library/ArmPlatformLib/ArmPlatformLib.inf | 1 +
.../Library/ArmPlatformLib/ArmPlatformLib.c | 17 +++++++++++++++++
5 files changed, 33 insertions(+)

diff --git a/Silicon/NXP/NxpQoriqLs.dec b/Silicon/NXP/NxpQoriqLs.dec
index 0c3608696569..3a568c0437e7 100644
--- a/Silicon/NXP/NxpQoriqLs.dec
+++ b/Silicon/NXP/NxpQoriqLs.dec
@@ -29,6 +29,7 @@ [PcdsFeatureFlag]
gNxpQoriqLsTokenSpaceGuid.PcdDcfgBigEndian|FALSE|BOOLEAN|0x00000316
gNxpQoriqLsTokenSpaceGuid.PcdPciLutBigEndian|FALSE|BOOLEAN|0x00000317
gNxpQoriqLsTokenSpaceGuid.PcdSataErratumA009185|FALSE|BOOLEAN|0x00000318
+ gNxpQoriqLsTokenSpaceGuid.PcdGpioControllerBigEndian|FALSE|BOOLEAN|0x00000319

[PcdsFixedAtBuild.common]
# Pcds for PCI Express
@@ -48,6 +49,13 @@ [PcdsFixedAtBuild.common]
gNxpQoriqLsTokenSpaceGuid.PcdSataSize|0x0|UINT32|0x00000351
gNxpQoriqLsTokenSpaceGuid.PcdNumSataController|0x0|UINT32|0x00000352

+ #
+ # Pcds for Gpio
+ #
+ gNxpQoriqLsTokenSpaceGuid.PcdNumGpioController|0|UINT32|0x00000355
+ gNxpQoriqLsTokenSpaceGuid.PcdGpioModuleBaseAddress|0|UINT64|0x00000356
+ gNxpQoriqLsTokenSpaceGuid.PcdGpioControllerOffset|0|UINT64|0x00000357
+
[PcdsDynamic.common]
gNxpQoriqLsTokenSpaceGuid.PcdPciCfgShiftEnable|FALSE|BOOLEAN|0x00000600
gNxpQoriqLsTokenSpaceGuid.PcdPciLsGen4Ctrl|FALSE|BOOLEAN|0x00000601
diff --git a/Silicon/NXP/LS1046A/LS1046A.dsc.inc b/Silicon/NXP/LS1046A/LS1046A.dsc.inc
index dbe7f408fce9..db110553605f 100644
--- a/Silicon/NXP/LS1046A/LS1046A.dsc.inc
+++ b/Silicon/NXP/LS1046A/LS1046A.dsc.inc
@@ -27,9 +27,14 @@ [PcdsDynamicDefault.common]

[PcdsFixedAtBuild.common]
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x021c0500
+ gNxpQoriqLsTokenSpaceGuid.PcdNumGpioController|0x04
+ gNxpQoriqLsTokenSpaceGuid.PcdGpioModuleBaseAddress|0x02300000
+ gNxpQoriqLsTokenSpaceGuid.PcdGpioControllerOffset|0x10000
+

[PcdsFeatureFlag]
gNxpQoriqLsTokenSpaceGuid.PcdDcfgBigEndian|TRUE
+ gNxpQoriqLsTokenSpaceGuid.PcdGpioControllerBigEndian|TRUE

################################################################################
#
diff --git a/Silicon/NXP/NxpQoriqLs.dsc.inc b/Silicon/NXP/NxpQoriqLs.dsc.inc
index fc600de01d74..21c87df73220 100644
--- a/Silicon/NXP/NxpQoriqLs.dsc.inc
+++ b/Silicon/NXP/NxpQoriqLs.dsc.inc
@@ -103,6 +103,8 @@ [LibraryClasses.common]
MemoryInitPeiLib|Silicon/NXP/Library/MemoryInitPeiLib/MemoryInitPeiLib.inf
UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf

+ GpioLib|Silicon/NXP/Library/GpioLib/GpioLib.inf
+
[LibraryClasses.common.SEC]
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
DebugAgentLib|ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf
diff --git a/Platform/NXP/LS1046aFrwyPkg/Library/ArmPlatformLib/ArmPlatformLib.inf b/Platform/NXP/LS1046aFrwyPkg/Library/ArmPlatformLib/ArmPlatformLib.inf
index 7802696bf39b..2e755842a714 100644
--- a/Platform/NXP/LS1046aFrwyPkg/Library/ArmPlatformLib/ArmPlatformLib.inf
+++ b/Platform/NXP/LS1046aFrwyPkg/Library/ArmPlatformLib/ArmPlatformLib.inf
@@ -25,6 +25,7 @@ [Packages]
[LibraryClasses]
ArmLib
DebugLib
+ GpioLib
SocLib

[Sources.common]
diff --git a/Platform/NXP/LS1046aFrwyPkg/Library/ArmPlatformLib/ArmPlatformLib.c b/Platform/NXP/LS1046aFrwyPkg/Library/ArmPlatformLib/ArmPlatformLib.c
index e1f20da09337..d467992a3e47 100644
--- a/Platform/NXP/LS1046aFrwyPkg/Library/ArmPlatformLib/ArmPlatformLib.c
+++ b/Platform/NXP/LS1046aFrwyPkg/Library/ArmPlatformLib/ArmPlatformLib.c
@@ -8,11 +8,14 @@

#include <Library/ArmLib.h>
#include <Library/ArmPlatformLib.h>
+#include <Library/GpioLib.h>
#include <Library/SocLib.h>

#include <Ppi/ArmMpCoreInfo.h>
#include <Ppi/NxpPlatformGetClock.h>

+#define USB2_MUX_SEL_GPIO 23
+
ARM_CORE_INFO mLS1046aMpCoreInfoTable[] = {
{
// Cluster 0, Core 0
@@ -89,6 +92,19 @@ NxpPlatformGetClock(
}

/**
+ FRWY-LS1046A GPIO 23 use for USB2
+ mux seclection
+**/
+STATIC VOID MuxSelectUsb2 (VOID)
+{
+
+ SetDir (GPIO3, USB2_MUX_SEL_GPIO, OUTPUT);
+ SetData (GPIO3, USB2_MUX_SEL_GPIO, HIGH);
+
+ return;
+}
+
+/**
Initialize controllers that must setup in the normal world

This function is called by the ArmPlatformPkg/PrePi or ArmPlatformPkg/PlatformPei
@@ -101,6 +117,7 @@ ArmPlatformInitialize (
)
{
SocInit ();
+ MuxSelectUsb2 ();

return EFI_SUCCESS;
}
--
1.9.1


[edk2-platforms 1/4] Silicon/NXP: Add GPIO driver support.

Meenakshi Aggarwal <meenakshi.aggarwal@...>
 

Signed-off-by: Pramod Kumar <pramod.kumar_1@nxp.com>
Signed-off-by: Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>
---
Silicon/NXP/Library/GpioLib/GpioLib.inf | 39 +++++
Silicon/NXP/Include/Library/GpioLib.h | 110 +++++++++++++++
Silicon/NXP/Library/GpioLib/GpioLib.c | 242 ++++++++++++++++++++++++++++++++
3 files changed, 391 insertions(+)
create mode 100644 Silicon/NXP/Library/GpioLib/GpioLib.inf
create mode 100644 Silicon/NXP/Include/Library/GpioLib.h
create mode 100644 Silicon/NXP/Library/GpioLib/GpioLib.c

diff --git a/Silicon/NXP/Library/GpioLib/GpioLib.inf b/Silicon/NXP/Library/GpioLib/GpioLib.inf
new file mode 100644
index 000000000000..7878d1d03db2
--- /dev/null
+++ b/Silicon/NXP/Library/GpioLib/GpioLib.inf
@@ -0,0 +1,39 @@
+/** @file
+
+ Copyright 2020 NXP
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+[Defines]
+ INF_VERSION = 0x0001001A
+ BASE_NAME = GpioLib
+ FILE_GUID = addec2b8-d2e0-43c0-a277-41a8d42f3f4f
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = GpioLib
+
+[Sources.common]
+ GpioLib.c
+
+[LibraryClasses]
+ ArmLib
+ BaseMemoryLib
+ BaseLib
+ IoAccessLib
+ IoLib
+
+[Packages]
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ Silicon/NXP/NxpQoriqLs.dec
+
+[Pcd]
+ gNxpQoriqLsTokenSpaceGuid.PcdNumGpioController
+ gNxpQoriqLsTokenSpaceGuid.PcdGpioModuleBaseAddress
+ gNxpQoriqLsTokenSpaceGuid.PcdGpioControllerOffset
+
+[FeaturePcd]
+ gNxpQoriqLsTokenSpaceGuid.PcdGpioControllerBigEndian
diff --git a/Silicon/NXP/Include/Library/GpioLib.h b/Silicon/NXP/Include/Library/GpioLib.h
new file mode 100644
index 000000000000..5821806226ee
--- /dev/null
+++ b/Silicon/NXP/Include/Library/GpioLib.h
@@ -0,0 +1,110 @@
+/** @file
+
+ Copyright 2020 NXP
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef GPIO_H__
+#define GPIO_H__
+
+#include <Uefi.h>
+
+/* enum for GPIO number */
+typedef enum _GPIO_BLOCK {
+ GPIO1,
+ GPIO2,
+ GPIO3,
+ GPIO4,
+ GPIO_MAX
+} GPIO_BLOCK;
+
+/* enum for GPIO direction */
+typedef enum _GPIO_DIRECTION {
+ INPUT,
+ OUTPUT
+} GPIO_DIRECTION;
+
+/* enum for GPIO state */
+typedef enum _GPIO_STATE {
+ LOW,
+ HIGH
+} GPIO_VAL;
+
+/**
+ SetDir Set GPIO direction as INPUT or OUTPUT
+
+ @param[in] Id GPIO controller number
+ @param[in] Bit GPIO number
+ @param[in] Dir GPIO Direction as INPUT or OUTPUT
+
+ @retval EFI_SUCCESS
+ **/
+EFI_STATUS
+SetDir (
+ IN UINT8 Id,
+ IN UINT32 Bit,
+ IN BOOLEAN Dir
+ );
+
+/**
+ GetDir Retrieve GPIO direction
+
+ @param[in] Id GPIO controller number
+ @param[in] Bit GPIO number
+
+ @retval GPIO Direction as INPUT or OUTPUT
+ **/
+UINT32
+GetDir (
+ IN UINT8 Id,
+ IN UINT32 Bit
+ );
+
+ /**
+ GetData Retrieve GPIO Value
+
+ @param[in] Id GPIO controller number
+ @param[in] Bit GPIO number
+
+ @retval GPIO value as HIGH or LOW
+ **/
+UINT32
+GetData (
+ IN UINT8 Id,
+ IN UINT32 Bit
+ );
+
+/**
+ SetData Set GPIO data Value
+
+ @param[in] Id GPIO controller number
+ @param[in] Bit GPIO number
+ @param[in] Data GPIO data value to set
+
+ @retval GPIO value as HIGH or LOW
+ **/
+EFI_STATUS
+SetData (
+ IN UINT8 Id,
+ IN UINT32 Bit,
+ IN BOOLEAN Data
+ );
+
+/**
+ SetOpenDrain Set GPIO as Open drain
+
+ @param[in] Id GPIO controller number
+ @param[in] Bit GPIO number
+ @param[in] OpenDrain Set as open drain
+
+ @retval EFI_SUCCESS
+ **/
+EFI_STATUS
+SetOpenDrain (
+ IN UINT8 Id,
+ IN UINT32 Bit,
+ IN BOOLEAN OpenDrain
+ );
+
+#endif
diff --git a/Silicon/NXP/Library/GpioLib/GpioLib.c b/Silicon/NXP/Library/GpioLib/GpioLib.c
new file mode 100644
index 000000000000..33cc45c2152b
--- /dev/null
+++ b/Silicon/NXP/Library/GpioLib/GpioLib.c
@@ -0,0 +1,242 @@
+/** @file
+
+ Copyright 2020 NXP
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/GpioLib.h>
+#include <Library/IoAccessLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+
+STATIC MMIO_OPERATIONS *mGpioOps;
+
+/* Structure for GPIO Regsters */
+typedef struct GpioRegs {
+ UINT32 GpDir;
+ UINT32 GpOdr;
+ UINT32 GpData;
+ UINT32 GpIer;
+ UINT32 GpImr;
+ UINT32 GpIcr;
+} GPIO_REGS;
+
+/**
+ GetBaseAddr GPIO controller Base Address
+
+ @param[in] Id GPIO controller number
+
+ @retval GPIO controller Base Address, if found
+ @retval NULL, if not a valid controller number
+
+ **/
+STATIC
+VOID *
+GetBaseAddr (
+ IN UINT8 Id
+ )
+{
+
+ UINTN GpioBaseAddr;
+ UINTN MaxGpioController;
+
+ mGpioOps = GetMmioOperations (FeaturePcdGet (PcdGpioControllerBigEndian));
+
+ MaxGpioController = PcdGet32 (PcdNumGpioController);
+
+ if (Id < MaxGpioController) {
+ GpioBaseAddr = PcdGet64 (PcdGpioModuleBaseAddress) +
+ (Id * PcdGet64 (PcdGpioControllerOffset));
+ return (VOID *) GpioBaseAddr;
+ }
+ else {
+ DEBUG((DEBUG_ERROR, "Invalid Gpio Controller Id %d, Allowed Ids are %d-%d",
+ Id, GPIO1, MaxGpioController));
+ return NULL;
+ }
+}
+
+/**
+ GetBitMask: Return Bit Mask
+
+ @param[in] Bit Bit to create bitmask
+ @retval Bitmask
+
+ **/
+
+STATIC
+UINT32
+GetBitMask (
+ IN UINT32 Bit
+ )
+{
+
+ if (!FeaturePcdGet (PcdGpioControllerBigEndian)) {
+ return (1 << Bit);
+ } else {
+ return (1 << (31 - Bit));
+ }
+}
+
+
+/**
+ SetDir Set GPIO direction as INPUT or OUTPUT
+
+ @param[in] Id GPIO controller number
+ @param[in] Bit GPIO number
+ @param[in] Dir GPIO Direction as INPUT or OUTPUT
+
+ @retval EFI_SUCCESS
+ **/
+EFI_STATUS
+SetDir (
+ IN UINT8 Id,
+ IN UINT32 Bit,
+ IN BOOLEAN Dir
+ )
+{
+ GPIO_REGS *Regs;
+ UINT32 BitMask;
+ UINT32 Value;
+
+ Regs = GetBaseAddr(Id);
+ BitMask = GetBitMask(Bit);
+
+ Value = mGpioOps->Read32 ((UINTN)&Regs->GpDir);
+
+ if (Dir) {
+ mGpioOps->Write32 ((UINTN)&Regs->GpDir, (Value | BitMask));
+ }
+ else {
+ mGpioOps->Write32 ((UINTN)&Regs->GpDir, (Value & (~BitMask)));
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ GetDir Retrieve GPIO direction
+
+ @param[in] Id GPIO controller number
+ @param[in] Bit GPIO number
+
+ @retval GPIO Direction as INPUT or OUTPUT
+ **/
+UINT32
+GetDir (
+ IN UINT8 Id,
+ IN UINT32 Bit
+ )
+{
+ GPIO_REGS *Regs;
+ UINT32 Value;
+ UINT32 BitMask;
+
+ Regs = GetBaseAddr (Id);
+ BitMask = GetBitMask(Bit);
+
+ Value = mGpioOps->Read32 ((UINTN)&Regs->GpDir);
+
+ return (Value & BitMask);
+}
+
+/**
+ GetData Retrieve GPIO Value
+
+ @param[in] Id GPIO controller number
+ @param[in] Bit GPIO number
+
+ @retval GPIO value as HIGH or LOW
+ **/
+UINT32
+GetData (
+ IN UINT8 Id,
+ IN UINT32 Bit
+ )
+{
+ GPIO_REGS *Regs;
+ UINT32 Value;
+ UINT32 BitMask;
+
+ Regs = (VOID *)GetBaseAddr (Id);
+ BitMask = GetBitMask(Bit);
+
+
+ Value = mGpioOps->Read32 ((UINTN)&Regs->GpData);
+
+ if (Value & BitMask) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+/**
+ SetData Set GPIO data Value
+
+ @param[in] Id GPIO controller number
+ @param[in] Bit GPIO number
+ @param[in] Data GPIO data value to set
+
+ @retval GPIO value as HIGH or LOW
+ **/
+EFI_STATUS
+SetData (
+ IN UINT8 Id,
+ IN UINT32 Bit,
+ IN BOOLEAN Data
+ )
+{
+ GPIO_REGS *Regs;
+ UINT32 BitMask;
+ UINT32 Value;
+
+ Regs = GetBaseAddr (Id);
+ BitMask = GetBitMask(Bit);
+
+ Value = mGpioOps->Read32 ((UINTN)&Regs->GpData);
+
+ if (Data) {
+ mGpioOps->Write32 ((UINTN)&Regs->GpData, (Value | BitMask));
+ } else {
+ mGpioOps->Write32 ((UINTN)&Regs->GpData, (Value & (~BitMask)));
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ SetOpenDrain Set GPIO as Open drain
+
+ @param[in] Id GPIO controller number
+ @param[in] Bit GPIO number
+ @param[in] OpenDrain Set as open drain
+
+ @retval EFI_SUCCESS
+ **/
+EFI_STATUS
+SetOpenDrain (
+ IN UINT8 Id,
+ IN UINT32 Bit,
+ IN BOOLEAN OpenDrain
+ )
+{
+ GPIO_REGS *Regs;
+ UINT32 BitMask;
+ UINT32 Value;
+
+ Regs = GetBaseAddr (Id);
+ BitMask = GetBitMask(Bit);
+
+ Value = mGpioOps->Read32 ((UINTN)&Regs->GpOdr);
+ if (OpenDrain) {
+ mGpioOps->Write32 ((UINTN)&Regs->GpOdr, (Value | BitMask));
+ }
+ else {
+ mGpioOps->Write32 ((UINTN)&Regs->GpOdr, (Value & (~BitMask)));
+ }
+
+ return EFI_SUCCESS;
+}
--
1.9.1