Date   

Re: [PATCH] Maintainers.txt: Update email address

Chang, Abner
 

[AMD Official Use Only - General]

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

-----Original Message-----
From: Nickle Wang <nicklew@...>
Sent: Thursday, September 15, 2022 10:20 AM
To: devel@edk2.groups.io
Cc: Andrew Fish <afish@...>; Leif Lindholm
<quic_llindhol@...>; Michael D Kinney <michael.d.kinney@...>;
Chang, Abner <Abner.Chang@...>
Subject: [PATCH] Maintainers.txt: Update email address

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


Update Nickle's email address from csie.io to nvidia.com for those packages
which are reviewed by Nickle. Per suggestion from Abner, change Nickle from
reviewer to maintainer for RedfishPkg.

Cc: Andrew Fish <afish@...>
Cc: Leif Lindholm <quic_llindhol@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Abner Chang <abner.chang@...>
Signed-off-by: Nickle Wang <nicklew@...>
---
Maintainers.txt | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Maintainers.txt b/Maintainers.txt index 73ce13126b..390f084c03
100644
--- a/Maintainers.txt
+++ b/Maintainers.txt
@@ -197,7 +197,7 @@ S: Maintained
EmulatorPkg: Redfish-related modules
F: EmulatorPkg/*Redfish*
M: Abner Chang <abner.chang@...> [changab]
-R: Nickle Wang <nickle@...> [nicklela]
+M: Nickle Wang <nicklew@...> [nicklela]

FatPkg
F: FatPkg/
@@ -544,7 +544,7 @@ R: Ankit Sinha <ankit.sinha@...> [ankit13s]
RedfishPkg: Redfish related modules
F: RedfishPkg/
M: Abner Chang <abner.chang@...> [changab]
-R: Nickle Wang <nickle@...> [nicklela]
+M: Nickle Wang <nicklew@...> [nicklela]

SecurityPkg
F: SecurityPkg/
--
2.34.1


Re: [PATCH v1] MdeModulePkg/AhciPei: Fix MMIO base assignment

Wu, Hao A
 

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Wu, Hao
A
Sent: Tuesday, September 13, 2022 12:36 PM
To: Czajkowski, Maciej <maciej.czajkowski@...>;
devel@edk2.groups.io
Cc: Ni, Ray <ray.ni@...>
Subject: Re: [edk2-devel] [PATCH v1] MdeModulePkg/AhciPei: Fix MMIO
base assignment

Reviewed-by: Hao A Wu <hao.a.wu@...>

Best Regards,
Hao Wu

-----Original Message-----
From: Czajkowski, Maciej <maciej.czajkowski@...>
Sent: Saturday, September 10, 2022 2:11 AM
To: devel@edk2.groups.io
Cc: Wu, Hao A <hao.a.wu@...>; Ni, Ray <ray.ni@...>
Subject: [PATCH v1] MdeModulePkg/AhciPei: Fix MMIO base assignment

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

There is a mistake in getting MMIO base using PciDevicePpi that can
lead to the data corruption.

Cc: Hao A Wu <hao.a.wu@...>
Cc: Ray Ni <ray.ni@...>
Signed-off-by: Maciej Czajkowski <maciej.czajkowski@...>
---
MdeModulePkg/Bus/Ata/AhciPei/AhciPei.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.c
b/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.c
index 98dd732a4023..47367f43f73a 100644
--- a/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.c
+++ b/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.c
@@ -405,7 +405,7 @@ AtaAhciInitPrivateDataFromPciDevice ( {

EFI_STATUS Status;

PCI_TYPE00 PciData;

- UINTN MmioBase;

+ UINT32 MmioBase;

EFI_DEVICE_PATH_PROTOCOL *DevicePath;

UINTN DevicePathLength;

UINT64 EnabledPciAttributes;

@@ -454,12 +454,13 @@ AtaAhciInitPrivateDataFromPciDevice (
&PciDevice->PciIo,

EfiPciIoWidthUint32,

0x24,

- sizeof (UINTN),

+ 1,

&MmioBase

);

if (EFI_ERROR (Status)) {

return EFI_UNSUPPORTED;

}

+ MmioBase &= 0xFFFFFFF0;



DevicePathLength = GetDevicePathSize (PciDevice->DevicePath);

DevicePath = PciDevice->DevicePath;

--
2.27.0.windows.1




Re: [PATCH] MdeModulePkg/Bus/Pci/XhciDxe: Fix the Bug of clean InputContext in XhcEvaluateContext64();

Wu, Hao A
 

Hello,

 

My take to the purpose of calling XhcEvaluateContext/XhcEvaluateContext64 functions is to “inform the xHC of the change to the Default Control endpoint’s Max Packet Size parameter.”

That is why the function only set bit 1 (Add Context bit 1) to inform the xHC only Endpoint Context for EP0 should be evaluated by xHC:

  InputContext->InputControlContext.Dword2 |= BIT1

 

I checked the xHCI spec, it does not prohibit only setting Add Context bit 1. According to section 4.6.7 Evaluate Context:

System software shall initialize Contexts of the

Input Context affected by the command. All Contexts not referenced by an Add Context flag in the Input

Context are ignored by the xHC.

 

If this is the case, the Slot Context should be ignored by the xHC, since Add Context bit 0 is cleared.

 

Then, according to section 6.2.3.3 Evaluate Context Command Usage:

A 'valid' Input Endpoint Context for an Evaluate Context Command requires that if the Add Context flag

(A1) for Default Control Endpoint is set to ‘1’, the Max Packet Size field shall be evaluated.

 

I do not think below code snippet violates with the above content in the spec:

  ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64));

 

  InputContext->InputControlContext.Dword2 |= BIT1;

  InputContext->EP[0].MaxPacketSize         = MaxPacketSize;

 

Do you have a chance to test other USB devices on your environment? Is it possible that the issue is a device specific case?

Thanks in advance.

 

Best Regards,

Hao Wu

 

From: Jiading Zhang <jdzhang@...>
Sent: Wednesday, September 14, 2022 5:23 PM
To: Wu; Wu, Hao A <hao.a.wu@...>; devel@edk2.groups.io
Subject: Re: [edk2-devel] [PATCH] MdeModulePkg/Bus/Pci/XhciDxe: Fix the Bug of clean InputContext in XhcEvaluateContext64();

 

When I use the newest XhciDxe driver in Phytium Platform( ARM) ,  I found if clearing “Input Context” in XhcEvaluateContext64(), the usb KB doesn't work, and mark the  code   ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64));  it works. 
I viewed the code again, maybe change the ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64)); to ZeroMem (InputContext, sizeof (INPUT_CONTRL_CONTEXT_64)); is more resonable.  Because when clearing the INPUT_CONTEXT_64, the Slot context and the endpoint context are cleared too. But according the xHCI Spec section 6.2.2 
NoteUnless otherwise stated: As Input, all fields of the Slot Context shall be initialized to the appropriate value by software before issuing a command.
And I test again, just clear INPUT_CONTRL_CONTEXT_64 is OK.


Re: How to guard CAR's stack overflow

Ni, Ray
 

It’s doable.

You need to enable paging and mark the very low 4K area of the stack as not-present.

You could use the UefiCpuPkg/Library/CpuPageTableLib to help you create the 1:1 page table with the specific
4K area as not-present (if you are using x86 processors).

 

Thanks,

Ray

 

From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Tiger Liu(BJ-RD)
Sent: Thursday, September 15, 2022 8:50 AM
To: devel@edk2.groups.io
Subject: [edk2-devel] How to guard CAR's stack overflow

 

Hi, Experts:

Usually, we use Cache As Ram to setup stack and heap for C language running environment before permanent memory has been initialized.

 

So, is there a method to guard this phases stack overflow?

 

Note:

I find udk has introduced a method to guard stack overflow after memory has been initialized and discovered.

 

Thanks

 

保密声明:

本邮件含有保密或专有信息,仅供指定收件人使用。严禁对本邮件或其内容做任何未经授权的查阅、使用、复制或转发。

CONFIDENTIAL NOTE:

This email contains confidential or legally privileged information and is for the sole use of its intended recipient. Any unauthorized review, use, copying or forwarding of this email or the content of this email is strictly prohibited.


Re: [PATCH v2] UnitTestFrameworkPkg: Add code coverage support for GCC

Guo, Gua
 

So if you run the stuart command with that plugin available on Linux/GCC, then both the  .gcda and HTML content is always generated and local user can either view HTML content with browser or view the results in VS Code with the .gcda files.  Correct? Yes, Correct.

 

I think there ways to run the stuart command for just that single pluigin specified on the command line, so the builds are as fast as possible during unit test development.  Would be good to capture that in the ReadMe.md as well. Let me think how to integrated into Edk2 appropriately

 

 

For VS builds, I have heard that OpenCppCoverage is a good option:

 

https://github.com/OpenCppCoverage/OpenCppCoverage

 

Wow, Don’t know the tool before.

 

 

 

Let me summary as below hope can eliminate your concern.

 

Windows

Linux

Compiler

VS2019

GCC5

Coverage Tool

https://github.com/OpenCppCoverage/OpenCppCoverage

https://github.com/linux-test-project/lcov

VS Code Extension Support

No, For long term, I may need to enough time to study OpenCppCoverage behavior.

And try to integrated into BIOS-CAT - Visual Studio Marketplace

Yes, Gcov Viewer - Visual Studio Marketplace

Coverage File type

*.pdb

*.gcda, *.gcno

Currently Behavior

(Will require [PATCH v2] UnitTestFrameworkPkg: Add code coverage support for GCC)

Step1. wget https://github.com/OpenCppCoverage/OpenCppCoverage/releases/download/release-0.9.9.0/OpenCppCoverageSetup-x64-0.9.9.0.exe

Step2. OpenCppCoverageSetup-x64-0.9.9.0.exe /SILENT

Step3. stuart_ci_build -c .pytool/CISettings.py  -t NOOPT TOOL_CHAIN_TAG=VS2019 -p MdePkg

Step4. OpenCppCoverage.exe --sources %cd% --export_type html:%cd%\Build\UnitTestReport -- %cd%\Build\MdePkg\HostTest\NOOPT_VS2019\X64\BaseLibUnitTestsHost.exe

Step5. Open "Build/UnitTestReport/index.html"

Step1. sudo apt-get install lcov

Step2. stuart_ci_build -c .pytool/CISettings.py -p MdePkg -t NOOPT TOOL_CHAIN_TAG=GCC5

Step3. lcov -c --rc lcov_branch_coverage=1 -o UnitTest.info -d Build/MdePkg/HostTest/NOOPT_GCC5/X64/MdePkg/

Step4. genhtml UnitTest.info --branch-coverage -o .Build/UnitTestReport

Step5. Open "Build/UnitTestReport/index.html"

Ideally Behavior (For Local Build)

(It may give me some time to think how to integrate the code into edk2\BaseTools\Plugin\HostBasedUnitTestRunner\HostBasedUnitTestRunner.py)

Step1. wget https://github.com/OpenCppCoverage/OpenCppCoverage/releases/download/release-0.9.9.0/OpenCppCoverageSetup-x64-0.9.9.0.exe

Step2. OpenCppCoverageSetup-x64-0.9.9.0.exe /SILENT

Step3. stuart_ci_build -c .pytool/CISettings.py  -t NOOPT TOOL_CHAIN_TAG=VS2019 -p MdePkg

Step4. Open "Build/Coverage.html"

 

Step1. sudo apt-get install lcov

Step2. stuart_ci_build -c .pytool/CISettings.py -p MdePkg -t NOOPT TOOL_CHAIN_TAG=GCC5

Step3. Open "Build/Coverage.html"

Ideally Behavior (For CI/CD)

 

It may give me some time to think how to modify.

edk2\.azurepipelines\Windows-VS2019.yml

It may give me some time to think how to modify.

edk2\.azurepipelines\Ubuntu-GCC5.yml

 

 

 

 


Thanks,

Gua

 

 

From: Kinney, Michael D <michael.d.kinney@...>
Sent: Thursday, September 15, 2022 12:35 AM
To: Guo, Gua <gua.guo@...>; Sean Brogan <spbrogan@...>; devel@edk2.groups.io; Kinney, Michael D <michael.d.kinney@...>
Cc: Sean Brogan <sean.brogan@...>; Michael Kubacki <mikuback@...>
Subject: RE: [edk2-devel] [PATCH v2] UnitTestFrameworkPkg: Add code coverage support for GCC

 

So if you run the stuart command with that plugin available on Linux/GCC, then both the  .gcda and HTML content is always generated and local user can either view HTML content with browser or view the results in VS Code with the .gcda files.  Correct?

 

I think there ways to run the stuart command for just that single pluigin specified on the command line, so the builds are as fast as possible during unit test development.  Would be good to capture that in the ReadMe.md as well.

 

Thanks,

 

Mike

 

From: Guo, Gua <gua.guo@...>
Sent: Tuesday, September 13, 2022 7:11 PM
To: Kinney, Michael D <michael.d.kinney@...>; Sean Brogan <spbrogan@...>; devel@edk2.groups.io
Cc: Sean Brogan <sean.brogan@...>; Michael Kubacki <mikuback@...>
Subject: RE: [edk2-devel] [PATCH v2] UnitTestFrameworkPkg: Add code coverage support for GCC

 

@Sean Brogan

 

I go through the code Merged PR 5008: Initial implementation or code coverage on basecore u… · microsoft/mu_basecore@f6af51f (github.com)

It looks good from my view point.

 

@Kinney, Michael D

Does that pytool plugin support viewing the code coverage visually in C source files? Yes

Either HTML or preferably an Visual Studio Code plugin? I think it can be supported by both based on below change. Due to VScode plugin is auto scan *.gcda and show the result in VScode source tree.
Merged PR 5008: Initial implementation or code coverage on basecore u… · microsoft/mu_basecore@f6af51f (github.com)

 

Flow for stuart_ci_build: (a) -> (b) -> (c) -> (d) -> (e) -> (f)

Flow for vscode extension Gcov Viewer - Visual Studio Marketplace:  (a) -> (b) -> (c) -> (d) -> (g)


(a) stuart_ci_build -p XXXPkg

(b) Call Edk2/.pytool/Plugin/HostUnitTestCompilerPlugin/HostUnitTestCompilerPlugin.py

(c) Call Edk2/BaseTools/Plugin/HostBasedUnitTestRunner/HostBasedUnitTestRunner.py

(d)       execute Build/XXXPkg/**/*Test* -> generate *.gcda files

(e)       use “lcov” tool to parse *.gcda

(f)        use “pycobertura” tool to generate index.html

(g) vscode extension to parse *.gcda and show it on source code directly.


Can it be updated to support VS compilers tool? No, currently I don’t find a good way to generate code coverage for MSVC compiler

 

Thanks,

Gua

From: Kinney, Michael D <michael.d.kinney@...>
Sent: Wednesday, September 14, 2022 9:52 AM
To: Sean Brogan <spbrogan@...>; devel@edk2.groups.io; Guo, Gua <gua.guo@...>; Kinney, Michael D <michael.d.kinney@...>
Cc: Sean Brogan <sean.brogan@...>; Michael Kubacki <mikuback@...>
Subject: RE: [edk2-devel] [PATCH v2] UnitTestFrameworkPkg: Add code coverage support for GCC

 

Does that pytool plugin support viewing the code coverage visually in C source files?

 

Either HTML or preferably an Visual Studio Code plugin?

 

Can it be updated to support VS compilers tool?

 

Mie

 

From: Sean Brogan <spbrogan@...>
Sent: Tuesday, September 13, 2022 6:18 PM
To: devel@edk2.groups.io; Guo, Gua <gua.guo@...>
Cc: Kinney, Michael D <michael.d.kinney@...>; Sean Brogan <sean.brogan@...>; Michael Kubacki <mikuback@...>
Subject: Re: [edk2-devel] [PATCH v2] UnitTestFrameworkPkg: Add code coverage support for GCC

 

Hi Gua Guo,

I would propose that we make this easier for both the local user and the CI system to get coverage metrics. 

Can you review this commit as it uses the same Edk2 plugins but adds code coverage support with GCC5:

Merged PR 5008: Initial implementation or code coverage on basecore u… · microsoft/mu_basecore@f6af51f (github.com)

 

Thanks

Sean

 

 

On 9/13/2022 6:01 PM, Guo, Gua wrote:

From: Gua Guo <gua.guo@...>
 
In order to collect code coverage after running executable
file, generate *.gcda and *.gcno file that require by lcov tool
to generate code coverage report.
 
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Sean Brogan <sean.brogan@...>
Cc: Bret Barkelew <Bret.Barkelew@...>
Cc: Michael Kubacki <mikuback@...>
Signed-off-by: Gua Guo <gua.guo@...>
---
 UnitTestFrameworkPkg/ReadMe.md                        | 116 +++++++++++++++++++-
 UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc |   2 +-
 2 files changed, 116 insertions(+), 2 deletions(-)
 
diff --git a/UnitTestFrameworkPkg/ReadMe.md b/UnitTestFrameworkPkg/ReadMe.md
index e696412cb3..93fdacfc4a 100644
--- a/UnitTestFrameworkPkg/ReadMe.md
+++ b/UnitTestFrameworkPkg/ReadMe.md
@@ -361,7 +361,7 @@ RUNNING TEST SUITE: Int Safe Conversions Test Suite
 ```
 
 
 
 You can also, if you are so inclined, read the output from the exact instance of the test that was run during
 
-`stuart_ci_build`. The ouput file can be found on a path that looks like:
 
+`stuart_ci_build`. The output file can be found on a path that looks like:
 
 
 
 `Build/<Package>/HostTest/<Arch>/<TestName>.<TestSuiteName>.<Arch>.result.xml`
 
 
 
@@ -399,6 +399,120 @@ CMOCKA_XML_FILE=<absolute or relative path to output file>
 
 
 This mode is used by the test running plugin to aggregate the results for CI test status reporting in the web view.
 
 
 
+### Enable Code Coverage for GCC host-based tests
 
+
 
+LCOV is an extension of GCOV, a GNU tool which provides information about what parts of a program are actually executed (i.e. "covered") while running a particular test case. The extension consists of a set of scripts which build on the textual GCOV output to implement it.
 
+
 
+Documentation for LCOV can be found here:
 
+https://lcov.readthedocs.io/
 
+
 
+You can follow below steps to generate your code coverage report.
 
+
 
+
 
+
 
+```bash
 
+user@linux_machine:~/_uefi$stuart_ci_build -c .pytool/CISettings.py TOOL_CHAIN_TAG=GCC5 -p MdePkg -t NOOPT
 
+...
 
+user@linux_machine:~/_uefi$lcov -c --rc lcov_branch_coverage=1 -o UnitTest.info -d Build/MdePkg/HostTest/NOOPT_GCC5/X64/MdePkg/
 
+Capturing coverage data from Build/MdePkg/HostTest/NOOPT_GCC5/X64/MdePkg/
 
+Found gcov version: 9.4.0
 
+Using intermediate gcov format
 
+Scanning Build/MdePkg/HostTest/NOOPT_GCC5/X64/MdePkg/ for .gcda files ...
 
+Found 38 data files in Build/MdePkg/HostTest/NOOPT_GCC5/X64/MdePkg/
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/RShiftU64.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/Math64.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/SafeString.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/SwapBytes32.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/CpuDeadLoop.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/MultU64x64.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/LongJump.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/SetJump.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/BitField.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/String.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/DivU64x32Remainder.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/X64/GccInline.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/MultU64x32.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/MultS64x64.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/LinkedList.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/LShiftU64.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/DivU64x32.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/SwapBytes16.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/Unaligned.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/CheckSum.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/CopyMem.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/MemLibGuid.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/CompareMemWrapper.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/SetMemWrapper.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/SetMem64Wrapper.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/MemLibGeneric.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/CopyMemWrapper.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/SetMem.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/ZeroMemWrapper.gcda
 
+Processing Library/BasePrintLib/BasePrintLib/OUTPUT/PrintLibInternal.gcda
 
+Processing Library/BasePrintLib/BasePrintLib/OUTPUT/PrintLib.gcda
 
+Processing Library/BaseSafeIntLib/BaseSafeIntLib/OUTPUT/SafeIntLib64.gcda
 
+Processing Library/BaseSafeIntLib/BaseSafeIntLib/OUTPUT/SafeIntLib.gcda
 
+Processing Test/UnitTest/Library/BaseLib/BaseLibUnitTestsHost/OUTPUT/Base64UnitTest.gcda
 
+Processing Test/UnitTest/Library/BaseLib/BaseLibUnitTestsHost/OUTPUT/AutoGen.gcda
 
+Processing Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibHost/OUTPUT/SafeIntLibUintnIntnUnitTests64.gcda
 
+Processing Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibHost/OUTPUT/TestBaseSafeIntLib.gcda
 
+Processing Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibHost/OUTPUT/AutoGen.gcda
 
+
 
+user@linux_machine:~/_uefi$genhtml UnitTest.info --branch-coverage -o Build/UnitTestReport
 
+
 
+Reading data file UnitTest.info
 
+Found 38 entries.
 
+Found common filename prefix "~/_uefi/MdePkg/Library"
 
+Writing .css and .png files.
 
+Generating output.
 
+Processing file ~/_uefi/Build/MdePkg/HostTest/NOOPT_GCC5/X64/MdePkg/Test/UnitTest/Library/BaseLib/BaseLibUnitTestsHost/DEBUG/AutoGen.c
 
+Processing file ~/_uefi/Build/MdePkg/HostTest/NOOPT_GCC5/X64/MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibHost/DEBUG/AutoGen.c
 
+Processing file BaseLib/Unaligned.c
 
+Processing file BaseLib/CheckSum.c
 
+Processing file BaseLib/BitField.c
 
+Processing file BaseLib/DivU64x32.c
 
+Processing file BaseLib/CpuDeadLoop.c
 
+Processing file BaseLib/LongJump.c
 
+Processing file BaseLib/MultU64x64.c
 
+Processing file BaseLib/RShiftU64.c
 
+Processing file BaseLib/SwapBytes32.c
 
+Processing file BaseLib/SwapBytes16.c
 
+Processing file BaseLib/SetJump.c
 
+Processing file BaseLib/LinkedList.c
 
+Processing file BaseLib/LShiftU64.c
 
+Processing file BaseLib/SafeString.c
 
+Processing file BaseLib/String.c
 
+Processing file BaseLib/DivU64x32Remainder.c
 
+Processing file BaseLib/MultS64x64.c
 
+Processing file BaseLib/MultU64x32.c
 
+Processing file BaseLib/Math64.c
 
+Processing file BaseLib/X64/GccInline.c
 
+Processing file BaseMemoryLib/SetMemWrapper.c
 
+Processing file BaseMemoryLib/CompareMemWrapper.c
 
+Processing file BaseMemoryLib/SetMem64Wrapper.c
 
+Processing file BaseMemoryLib/ZeroMemWrapper.c
 
+Processing file BaseMemoryLib/CopyMemWrapper.c
 
+Processing file BaseMemoryLib/CopyMem.c
 
+Processing file BaseMemoryLib/SetMem.c
 
+Processing file BaseMemoryLib/MemLibGuid.c
 
+Processing file BaseMemoryLib/MemLibGeneric.c
 
+Processing file BasePrintLib/PrintLib.c
 
+Processing file BasePrintLib/PrintLibInternal.c
 
+Processing file BaseSafeIntLib/SafeIntLib64.c
 
+Processing file BaseSafeIntLib/SafeIntLib.c
 
+Processing file ~/_uefi/MdePkg/Test/UnitTest/Library/BaseLib/Base64UnitTest.c
 
+Processing file ~/_uefi/MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLib.c
 
+Processing file ~/_uefi/MdePkg/Test/UnitTest/Library/BaseSafeIntLib/SafeIntLibUintnIntnUnitTests64.c
 
+Writing directory view page.
 
+Overall coverage rate:
 
+  lines......: 58.6% (2688 of 4589 lines)
 
+  functions..: 57.1% (249 of 436 functions)
 
+  branches...: 25.3% (1062 of 4195 branches)
 
+
 
+...
 
+
 
+```
 
+
 
 ### Important Note
 
 
 
 This works on both Windows and Linux, but is currently limited to x64 architectures. Working on getting others, but we
 
diff --git a/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc b/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
index 4dd8d4ac67..8623aecb33 100644
--- a/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
+++ b/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
@@ -19,7 +19,7 @@
   MemoryAllocationLib|UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.inf
 
 
 
 [BuildOptions]
 
-  GCC:*_*_*_CC_FLAGS = -fno-pie
 
+  GCC:*_*_*_CC_FLAGS = -fno-pie -ftest-coverage -fprofile-arcs
 
 !ifdef $(UNIT_TESTING_DEBUG)
 
   MSFT:*_*_*_CC_FLAGS  = -D UNIT_TESTING_DEBUG=1
 
   GCC:*_*_*_CC_FLAGS   = -D UNIT_TESTING_DEBUG=1
 


Event: TianoCore Community Meeting - APAC/NAMO - 09/15/2022 #cal-reminder

Group Notification <noreply@...>
 

Reminder: TianoCore Community Meeting - APAC/NAMO

When:
09/15/2022
7:30pm to 8:30pm
(UTC-07:00) America/Los Angeles

Where:
https://teams.microsoft.com/l/meetup-join/19%3ameeting_Y2M1NDE3ODYtN2M3Yy00MDMxLTk3OWYtMTlkNjhlNWFlMjA2%40thread.v2/0?context=%7b%22Tid%22%3a%2246c98d88-e344-4ed4-8496-4ed7712e255d%22%2c%22Oid%22%3a%226e4ce4c4-1242-431b-9a51-92cd01a5df3c%22%7d

Organizer: Miki Demeter

View Event

Description:

 

________________________________________________________________________________

Microsoft Teams meeting

Join on your computer or mobile app

Click here to join the meeting

Meeting ID: 283 318 374 436
Passcode: 633zLo

Download Teams | Join on the web

Join with a video conferencing device

teams@...

Video Conference ID: 119 493 012 8

Alternate VTC instructions

Learn More | Meeting options

________________________________________________________________________________


How to guard CAR's stack overflow

Tiger Liu(BJ-RD)
 

Hi, Experts:

Usually, we use Cache As Ram to setup stack and heap for C language running environment before permanent memory has been initialized.

 

So, is there a method to guard this phase’s stack overflow?

 

Note:

I find udk has introduced a method to guard stack overflow after memory has been initialized and discovered.

 

Thanks



保密声明:
本邮件含有保密或专有信息,仅供指定收件人使用。严禁对本邮件或其内容做任何未经授权的查阅、使用、复制或转发。
CONFIDENTIAL NOTE:
This email contains confidential or legally privileged information and is for the sole use of its intended recipient. Any unauthorized review, use, copying or forwarding of this email or the content of this email is strictly prohibited.


[PATCH v2 2/3] DynamicTablesPkg: AML Code generation to add _CPC entries

Jeff Brasen
 

_CPC entries can describe CPU performance information.
The object is described in ACPI 6.4 s8.4.7.1.
"_CPC (Continuous Performance Control)".

Add AmlCreateCpcNode() helper function to add _CPC entries to an
existing CPU object.

Signed-off-by: Jeff Brasen <jbrasen@...>
---
.../Include/Library/AmlLib/AmlLib.h | 156 +++++
.../Common/AmlLib/CodeGen/AmlCodeGen.c | 543 ++++++++++++++++++
2 files changed, 699 insertions(+)

diff --git a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
index 39968660f2..3fafa6b0e8 100644
--- a/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
+++ b/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
@@ -1336,6 +1336,162 @@ AmlAddNameIntegerPackage (
IN AML_OBJECT_NODE_HANDLE PackageNode
);

+/** Create a _CPC node.
+
+ Creates and optionally adds the following node
+ Name(_CPC, Package()
+ {
+ NumEntries, // Integer
+ Revision, // Integer
+ HighestPerformance, // Integer or Buffer (Resource Descriptor)
+ NominalPerformance, // Integer or Buffer (Resource Descriptor)
+ LowestNonlinearPerformance, // Integer or Buffer (Resource Descriptor)
+ LowestPerformance, // Integer or Buffer (Resource Descriptor)
+ GuaranteedPerformanceRegister, // Buffer (Resource Descriptor)
+ DesiredPerformanceRegister , // Buffer (Resource Descriptor)
+ MinimumPerformanceRegister , // Buffer (Resource Descriptor)
+ MaximumPerformanceRegister , // Buffer (Resource Descriptor)
+ PerformanceReductionToleranceRegister, // Buffer (Resource Descriptor)
+ TimeWindowRegister, // Buffer (Resource Descriptor)
+ CounterWraparoundTime, // Integer or Buffer (Resource Descriptor)
+ ReferencePerformanceCounterRegister, // Buffer (Resource Descriptor)
+ DeliveredPerformanceCounterRegister, // Buffer (Resource Descriptor)
+ PerformanceLimitedRegister, // Buffer (Resource Descriptor)
+ CPPCEnableRegister // Buffer (Resource Descriptor)
+ AutonomousSelectionEnable, // Integer or Buffer (Resource Descriptor)
+ AutonomousActivityWindowRegister, // Buffer (Resource Descriptor)
+ EnergyPerformancePreferenceRegister, // Buffer (Resource Descriptor)
+ ReferencePerformance // Integer or Buffer (Resource Descriptor)
+ LowestFrequency, // Integer or Buffer (Resource Descriptor)
+ NominalFrequency // Integer or Buffer (Resource Descriptor)
+ })
+
+ If resource buffer is NULL then integer will be used.
+
+ Cf. ACPI 6.4, s8.4.7.1 _CPC (Continuous Performance Control)
+
+ @ingroup CodeGenApis
+
+ @param [in] HighestPerformanceBuffer If provided, buffer that indicates the highest level
+ of performance the processor.
+ @param [in] HighestPerformanceInteger Indicates the highest level of performance the processor,
+ used if buffer is NULL.
+ @param [in] NominalPerformanceBuffer If provided buffer that indicates the highest sustained
+ performance level of the processor.
+ @param [in] NominalPerformanceInteger Indicates the highest sustained performance level
+ of the processor, used if buffer is NULL.
+ @param [in] LowestNonlinearPerformanceBuffer If provided, buffer that indicates the lowest performance level
+ of the processor with non-linear power savings.
+ @param [in] LowestNonlinearPerformanceInteger Indicates the lowest performance level of the processor with
+ non-linear power savings, used if buffer is NULL.
+ @param [in] LowestPerformanceBuffer If provided, buffer that indicates the
+ lowest performance level of the processor.
+ @param [in] LowestPerformanceInteger Indicates the lowest performance level of the processor,
+ used if buffer is NULL.
+ @param [in] GuaranteedPerformanceRegister If provided, Guaranteed Performance Register Buffer.
+ @param [in] DesiredPerformanceRegister If provided, Desired Performance Register Buffer.
+ @param [in] MinimumPerformanceRegister If provided, Minimum Performance Register Buffer.
+ @param [in] MaximumPerformanceRegister If provided, Maximum Performance Register Buffer.
+ @param [in] PerformanceReductionToleranceRegister If provided, Performance Reduction Tolerance Register.
+ @param [in] TimeWindowRegister If provided, Time Window Register.
+ @param [in] CounterWraparoundTimeBuffer If provided, Counter Wraparound Time buffer.
+ @param [in] CounterWraparoundTimeInteger Counter Wraparound Time, used if buffer is NULL.
+ @param [in] ReferencePerformanceCounterRegister Reference Performance Counter Register.
+ @param [in] DeliveredPerformanceCounterRegister Delivered Performance Counter Register.
+ @param [in] PerformanceLimitedRegister Performance Limited Register.
+ @param [in] CPPCEnableRegister If provided, CPPC EnableRegister.
+ @param [in] AutonomousSelectionEnableBuffer If provided, Autonomous Selection Enable buffer.
+ @param [in] AutonomousSelectionEnableInteger Autonomous Selection Enable, used if buffer is NULL.
+ @param [in] AutonomousActivityWindowRegister If provided, AutonomousActivity-WindowRegister.
+ @param [in] EnergyPerformancePreferenceRegister If provided, EnergyPerformance-PreferenceRegister.
+ @param [in] ReferencePerformanceBuffer If provided, Reference Performance buffer.
+ @param [in] ReferencePerformanceInteger Reference Performance, used if buffer is NULL.
+ @param [in] LowestFrequencyBuffer If provided, Lowest Frequency buffer.
+ @param [in] LowestFrequencyInteger Lowest Frequency, used if buffer is NULL.
+ @param [in] NominalFrequencyBuffer If provided, NominalFrequencyBuffer buffer.
+ @param [in] NominalFrequencyInteger NominalFrequencyBuffer, used if buffer is NULL.
+ @param [in] ParentNode If provided, set ParentNode as the parent
+ of the node created.
+ @param [out] NewCpcNode If success and provided, contains the created node.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+AmlCreateCpcNode (
+ /// The revision number of the _CPC package format.
+ IN UINT32 Revision,
+ /// Indicates the highest level of performance the processor
+ /// is theoretically capable of achieving.
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *HighestPerformanceBuffer OPTIONAL,
+ IN UINT32 HighestPerformanceInteger,
+ /// Indicates the highest sustained performance level of the processor.
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *NominalPerformanceBuffer OPTIONAL,
+ IN UINT32 NominalPerformanceInteger,
+ /// Indicates the lowest performance level of the processor with non-linear power savings.
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *LowestNonlinearPerformanceBuffer OPTIONAL,
+ IN UINT32 LowestNonlinearPerformanceInteger,
+ /// Indicates the lowest performance level of the processor..
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *LowestPerformanceBuffer OPTIONAL,
+ IN UINT32 LowestPerformanceInteger,
+ /// Guaranteed Performance Register Buffer.
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *GuaranteedPerformanceRegister OPTIONAL,
+ /// Desired Performance Register Buffer.
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *DesiredPerformanceRegister,
+ /// Minimum Performance Register Buffer.
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *MinimumPerformanceRegister OPTIONAL,
+ /// Maximum Performance Register Buffer.
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *MaximumPerformanceRegister OPTIONAL,
+ /// Performance Reduction Tolerance Register.
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *PerformanceReductionToleranceRegister OPTIONAL,
+ /// Time Window Register.
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *TimeWindowRegister OPTIONAL,
+ /// Counter Wraparound Time
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *CounterWraparoundTimeBuffer OPTIONAL,
+ IN UINT32 CounterWraparoundTimeInteger,
+ /// Reference Performance Counter Register
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *ReferencePerformanceCounterRegister,
+ /// Delivered Performance Counter Register
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *DeliveredPerformanceCounterRegister,
+ /// Performance Limited Register
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *PerformanceLimitedRegister,
+ /// CPPC EnableRegister
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *CPPCEnableRegister OPTIONAL,
+ /// Autonomous Selection Enable
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *AutonomousSelectionEnableBuffer OPTIONAL,
+ IN UINT32 AutonomousSelectionEnableInteger,
+ /// AutonomousActivity-WindowRegister
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *AutonomousActivityWindowRegister OPTIONAL,
+ /// EnergyPerformance-PreferenceRegister
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *EnergyPerformancePreferenceRegister OPTIONAL,
+ /// Reference Performance
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *ReferencePerformanceBuffer OPTIONAL,
+ IN UINT32 ReferencePerformanceInteger,
+ /// Lowest Frequency
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *LowestFrequencyBuffer OPTIONAL,
+ IN UINT32 LowestFrequencyInteger,
+ /// Nominal Frequency
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *NominalFrequencyBuffer OPTIONAL,
+ IN UINT32 NominalFrequencyInteger,
+ IN AML_NODE_HANDLE ParentNode OPTIONAL,
+ OUT AML_OBJECT_NODE_HANDLE *NewCpcNode OPTIONAL
+ );
+
// DEPRECATED APIS
#ifndef DISABLE_NEW_DEPRECATED_INTERFACES

diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
index 5fb39d077b..42f0d0002c 100644
--- a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
+++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlCodeGen.c
@@ -2850,3 +2850,546 @@ error_handler:

return Status;
}
+
+/** Adds a register to the package
+
+ @ingroup CodeGenApis
+
+ @param [in] Register If provided, register that will be added to package.
+ otherwise NULL register will be added
+ @param [in] PackageNode Package to add value to
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+AmlAddRegisterToPackage (
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *Register OPTIONAL,
+ IN AML_OBJECT_NODE_HANDLE PackageNode
+ )
+{
+ EFI_STATUS Status;
+ AML_DATA_NODE_HANDLE RdNode;
+ AML_OBJECT_NODE_HANDLE ResourceTemplateNode;
+
+ RdNode = NULL;
+
+ Status = AmlCodeGenResourceTemplate (&ResourceTemplateNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ if (Register != NULL) {
+ Status = AmlCodeGenRdRegister (
+ Register->AddressSpaceId,
+ Register->RegisterBitWidth,
+ Register->RegisterBitOffset,
+ Register->Address,
+ Register->AccessSize,
+ NULL,
+ &RdNode
+ );
+ } else {
+ Status = AmlCodeGenRdRegister (
+ EFI_ACPI_6_4_SYSTEM_MEMORY,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ &RdNode
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAppendRdNode (ResourceTemplateNode, RdNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ RdNode = NULL;
+
+ Status = AmlVarListAddTail (
+ (AML_NODE_HANDLE)PackageNode,
+ (AML_NODE_HANDLE)ResourceTemplateNode
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ return Status;
+
+error_handler:
+ if (RdNode != NULL) {
+ AmlDeleteTree ((AML_NODE_HANDLE)RdNode);
+ }
+
+ if (ResourceTemplateNode != NULL) {
+ AmlDeleteTree ((AML_NODE_HANDLE)ResourceTemplateNode);
+ }
+
+ return Status;
+}
+
+/** Adds an integer or register to the package
+
+ @ingroup CodeGenApis
+
+ @param [in] Register If provided, register that will be added to package
+ @param [in] Integer If Register is NULL, integer that will be added to the package
+ @param [in] PackageNode Package to add value to
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+AmlAddRegisterOrIntegerToPackage (
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *Register OPTIONAL,
+ IN UINT32 Integer,
+ IN AML_OBJECT_NODE_HANDLE PackageNode
+ )
+{
+ EFI_STATUS Status;
+ AML_OBJECT_NODE_HANDLE IntegerNode;
+
+ IntegerNode = NULL;
+
+ if (Register != NULL) {
+ Status = AmlAddRegisterToPackage (Register, PackageNode);
+ } else {
+ Status = AmlCodeGenInteger (Integer, &IntegerNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ Status = AmlVarListAddTail (
+ (AML_NODE_HANDLE)PackageNode,
+ (AML_NODE_HANDLE)IntegerNode
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ if (IntegerNode != NULL) {
+ AmlDeleteTree ((AML_NODE_HANDLE)IntegerNode);
+ }
+ }
+
+ return Status;
+}
+
+/** Create a _CPC node.
+
+ Creates and optionally adds the following node
+ Name(_CPC, Package()
+ {
+ NumEntries, // Integer
+ Revision, // Integer
+ HighestPerformance, // Integer or Buffer (Resource Descriptor)
+ NominalPerformance, // Integer or Buffer (Resource Descriptor)
+ LowestNonlinearPerformance, // Integer or Buffer (Resource Descriptor)
+ LowestPerformance, // Integer or Buffer (Resource Descriptor)
+ GuaranteedPerformanceRegister, // Buffer (Resource Descriptor)
+ DesiredPerformanceRegister , // Buffer (Resource Descriptor)
+ MinimumPerformanceRegister , // Buffer (Resource Descriptor)
+ MaximumPerformanceRegister , // Buffer (Resource Descriptor)
+ PerformanceReductionToleranceRegister, // Buffer (Resource Descriptor)
+ TimeWindowRegister, // Buffer (Resource Descriptor)
+ CounterWraparoundTime, // Integer or Buffer (Resource Descriptor)
+ ReferencePerformanceCounterRegister, // Buffer (Resource Descriptor)
+ DeliveredPerformanceCounterRegister, // Buffer (Resource Descriptor)
+ PerformanceLimitedRegister, // Buffer (Resource Descriptor)
+ CPPCEnableRegister // Buffer (Resource Descriptor)
+ AutonomousSelectionEnable, // Integer or Buffer (Resource Descriptor)
+ AutonomousActivityWindowRegister, // Buffer (Resource Descriptor)
+ EnergyPerformancePreferenceRegister, // Buffer (Resource Descriptor)
+ ReferencePerformance // Integer or Buffer (Resource Descriptor)
+ LowestFrequency, // Integer or Buffer (Resource Descriptor)
+ NominalFrequency // Integer or Buffer (Resource Descriptor)
+ })
+
+ If resource buffer is NULL then integer will be used.
+
+ Cf. ACPI 6.4, s8.4.7.1 _CPC (Continuous Performance Control)
+
+ @ingroup CodeGenApis
+
+ @param [in] HighestPerformanceBuffer If provided, buffer that indicates the highest level
+ of performance the processor.
+ @param [in] HighestPerformanceInteger Indicates the highest level of performance the processor,
+ used if buffer is NULL.
+ @param [in] NominalPerformanceBuffer If provided buffer that indicates the highest sustained
+ performance level of the processor.
+ @param [in] NominalPerformanceInteger Indicates the highest sustained performance level
+ of the processor, used if buffer is NULL.
+ @param [in] LowestNonlinearPerformanceBuffer If provided, buffer that indicates the lowest performance level
+ of the processor with non-linear power savings.
+ @param [in] LowestNonlinearPerformanceInteger Indicates the lowest performance level of the processor with
+ non-linear power savings, used if buffer is NULL.
+ @param [in] LowestPerformanceBuffer If provided, buffer that indicates the
+ lowest performance level of the processor.
+ @param [in] LowestPerformanceInteger Indicates the lowest performance level of the processor,
+ used if buffer is NULL.
+ @param [in] GuaranteedPerformanceRegister If provided, Guaranteed Performance Register Buffer.
+ @param [in] DesiredPerformanceRegister If provided, Desired Performance Register Buffer.
+ @param [in] MinimumPerformanceRegister If provided, Minimum Performance Register Buffer.
+ @param [in] MaximumPerformanceRegister If provided, Maximum Performance Register Buffer.
+ @param [in] PerformanceReductionToleranceRegister If provided, Performance Reduction Tolerance Register.
+ @param [in] TimeWindowRegister If provided, Time Window Register.
+ @param [in] CounterWraparoundTimeBuffer If provided, Counter Wraparound Time buffer.
+ @param [in] CounterWraparoundTimeInteger Counter Wraparound Time, used if buffer is NULL.
+ @param [in] ReferencePerformanceCounterRegister Reference Performance Counter Register.
+ @param [in] DeliveredPerformanceCounterRegister Delivered Performance Counter Register.
+ @param [in] PerformanceLimitedRegister Performance Limited Register.
+ @param [in] CPPCEnableRegister If provided, CPPC EnableRegister.
+ @param [in] AutonomousSelectionEnableBuffer If provided, Autonomous Selection Enable buffer.
+ @param [in] AutonomousSelectionEnableInteger Autonomous Selection Enable, used if buffer is NULL.
+ @param [in] AutonomousActivityWindowRegister If provided, AutonomousActivity-WindowRegister.
+ @param [in] EnergyPerformancePreferenceRegister If provided, EnergyPerformance-PreferenceRegister.
+ @param [in] ReferencePerformanceBuffer If provided, Reference Performance buffer.
+ @param [in] ReferencePerformanceInteger Reference Performance, used if buffer is NULL.
+ @param [in] LowestFrequencyBuffer If provided, Lowest Frequency buffer.
+ @param [in] LowestFrequencyInteger Lowest Frequency, used if buffer is NULL.
+ @param [in] NominalFrequencyBuffer If provided, NominalFrequencyBuffer buffer.
+ @param [in] NominalFrequencyInteger NominalFrequencyBuffer, used if buffer is NULL.
+ @param [in] ParentNode If provided, set ParentNode as the parent
+ of the node created.
+ @param [out] NewCpcNode If success and provided, contains the created node.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+AmlCreateCpcNode (
+ /// The revision number of the _CPC package format.
+ IN UINT32 Revision,
+ /// Indicates the highest level of performance the processor
+ /// is theoretically capable of achieving.
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *HighestPerformanceBuffer OPTIONAL,
+ IN UINT32 HighestPerformanceInteger,
+ /// Indicates the highest sustained performance level of the processor.
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *NominalPerformanceBuffer OPTIONAL,
+ IN UINT32 NominalPerformanceInteger,
+ /// Indicates the lowest performance level of the processor with non-linear power savings.
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *LowestNonlinearPerformanceBuffer OPTIONAL,
+ IN UINT32 LowestNonlinearPerformanceInteger,
+ /// Indicates the lowest performance level of the processor..
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *LowestPerformanceBuffer OPTIONAL,
+ IN UINT32 LowestPerformanceInteger,
+ /// Guaranteed Performance Register Buffer.
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *GuaranteedPerformanceRegister OPTIONAL,
+ /// Desired Performance Register Buffer.
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *DesiredPerformanceRegister,
+ /// Minimum Performance Register Buffer.
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *MinimumPerformanceRegister OPTIONAL,
+ /// Maximum Performance Register Buffer.
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *MaximumPerformanceRegister OPTIONAL,
+ /// Performance Reduction Tolerance Register.
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *PerformanceReductionToleranceRegister OPTIONAL,
+ /// Time Window Register.
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *TimeWindowRegister OPTIONAL,
+ /// Counter Wraparound Time
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *CounterWraparoundTimeBuffer OPTIONAL,
+ IN UINT32 CounterWraparoundTimeInteger,
+ /// Reference Performance Counter Register
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *ReferencePerformanceCounterRegister,
+ /// Delivered Performance Counter Register
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *DeliveredPerformanceCounterRegister,
+ /// Performance Limited Register
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *PerformanceLimitedRegister,
+ /// CPPC EnableRegister
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *CPPCEnableRegister OPTIONAL,
+ /// Autonomous Selection Enable
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *AutonomousSelectionEnableBuffer OPTIONAL,
+ IN UINT32 AutonomousSelectionEnableInteger,
+ /// AutonomousActivity-WindowRegister
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *AutonomousActivityWindowRegister OPTIONAL,
+ /// EnergyPerformance-PreferenceRegister
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *EnergyPerformancePreferenceRegister OPTIONAL,
+ /// Reference Performance
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *ReferencePerformanceBuffer OPTIONAL,
+ IN UINT32 ReferencePerformanceInteger,
+ /// Lowest Frequency
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *LowestFrequencyBuffer OPTIONAL,
+ IN UINT32 LowestFrequencyInteger,
+ /// Nominal Frequency
+ /// Optional
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *NominalFrequencyBuffer OPTIONAL,
+ IN UINT32 NominalFrequencyInteger,
+ IN AML_NODE_HANDLE ParentNode OPTIONAL,
+ OUT AML_OBJECT_NODE_HANDLE *NewCpcNode OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ AML_OBJECT_NODE_HANDLE CpcNode;
+ AML_OBJECT_NODE_HANDLE CpcPackage;
+ UINT32 NumberOfEntries;
+
+ // Revision 3 per ACPI 6.4 specification
+ if (Revision == 3) {
+ // NumEntries 23 per ACPI 6.4 specification
+ NumberOfEntries = 23;
+ } else {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (((HighestPerformanceBuffer == NULL) && (HighestPerformanceInteger == 0)) ||
+ ((NominalPerformanceBuffer == NULL) && (NominalPerformanceInteger == 0)) ||
+ ((LowestNonlinearPerformanceBuffer == NULL) && (LowestNonlinearPerformanceInteger == 0)) ||
+ ((LowestPerformanceBuffer == NULL) && (LowestPerformanceInteger == 0)) ||
+ (DesiredPerformanceRegister == NULL) ||
+ (ReferencePerformanceCounterRegister == NULL) ||
+ (DeliveredPerformanceCounterRegister == NULL) ||
+ (PerformanceLimitedRegister == NULL) ||
+ ((ParentNode == NULL) && (NewCpcNode == NULL)))
+ {
+ ASSERT (0);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CpcPackage = NULL;
+
+ Status = AmlCodeGenNamePackage ("_CPC", NULL, &CpcNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ // Get the Package object node of the _CPC node,
+ // which is the 2nd fixed argument (i.e. index 1).
+ CpcPackage = (AML_OBJECT_NODE_HANDLE)AmlGetFixedArgument (
+ CpcNode,
+ EAmlParseIndexTerm1
+ );
+ if ((CpcPackage == NULL) ||
+ (AmlGetNodeType ((AML_NODE_HANDLE)CpcPackage) != EAmlNodeObject) ||
+ (!AmlNodeHasOpCode (CpcPackage, AML_PACKAGE_OP, 0)))
+ {
+ ASSERT (0);
+ Status = EFI_INVALID_PARAMETER;
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterOrIntegerToPackage (
+ NULL,
+ NumberOfEntries,
+ CpcPackage
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterOrIntegerToPackage (
+ NULL,
+ Revision,
+ CpcPackage
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterOrIntegerToPackage (
+ HighestPerformanceBuffer,
+ HighestPerformanceInteger,
+ CpcPackage
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterOrIntegerToPackage (
+ NominalPerformanceBuffer,
+ NominalPerformanceInteger,
+ CpcPackage
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterOrIntegerToPackage (
+ LowestNonlinearPerformanceBuffer,
+ LowestNonlinearPerformanceInteger,
+ CpcPackage
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterOrIntegerToPackage (
+ LowestPerformanceBuffer,
+ LowestPerformanceInteger,
+ CpcPackage
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterToPackage (GuaranteedPerformanceRegister, CpcPackage);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterToPackage (DesiredPerformanceRegister, CpcPackage);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterToPackage (MinimumPerformanceRegister, CpcPackage);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterToPackage (MaximumPerformanceRegister, CpcPackage);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterToPackage (PerformanceReductionToleranceRegister, CpcPackage);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterToPackage (TimeWindowRegister, CpcPackage);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterOrIntegerToPackage (
+ CounterWraparoundTimeBuffer,
+ CounterWraparoundTimeInteger,
+ CpcPackage
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterToPackage (ReferencePerformanceCounterRegister, CpcPackage);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterToPackage (DeliveredPerformanceCounterRegister, CpcPackage);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterToPackage (PerformanceLimitedRegister, CpcPackage);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterToPackage (CPPCEnableRegister, CpcPackage);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterOrIntegerToPackage (
+ AutonomousSelectionEnableBuffer,
+ AutonomousSelectionEnableInteger,
+ CpcPackage
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterToPackage (AutonomousActivityWindowRegister, CpcPackage);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterToPackage (EnergyPerformancePreferenceRegister, CpcPackage);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterOrIntegerToPackage (
+ ReferencePerformanceBuffer,
+ ReferencePerformanceInteger,
+ CpcPackage
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterOrIntegerToPackage (
+ LowestFrequencyBuffer,
+ LowestFrequencyInteger,
+ CpcPackage
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = AmlAddRegisterOrIntegerToPackage (
+ NominalFrequencyBuffer,
+ NominalFrequencyInteger,
+ CpcPackage
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ Status = LinkNode (CpcNode, ParentNode, NewCpcNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ goto error_handler;
+ }
+
+ return Status;
+
+error_handler:
+ AmlDeleteTree ((AML_NODE_HANDLE)CpcNode);
+ return Status;
+}
--
2.25.1


[PATCH v2 1/3] DynamicTablesPkg: Add CM_ARM_CPC_INFO object

Jeff Brasen
 

Introduce the CM_ARM_CPC_INFO CmObj in the ArmNameSpaceObjects.
This allows to describe CPC information, as described in ACPI 6.4,
s8.4.7.1 "_CPC (Continuous Performance Control)".

Signed-off-by: Jeff Brasen <jbrasen@...>
---
.../Include/ArmNameSpaceObjects.h | 148 ++++++++++++++++--
.../ConfigurationManagerObjectParser.c | 79 ++++++++++
2 files changed, 210 insertions(+), 17 deletions(-)

diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
index 102e0f96be..d76cc08e14 100644
--- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
+++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
@@ -63,6 +63,7 @@ typedef enum ArmObjectID {
EArmObjPciInterruptMapInfo, ///< 39 - Pci Interrupt Map Info
EArmObjRmr, ///< 40 - Reserved Memory Range Node
EArmObjMemoryRangeDescriptor, ///< 41 - Memory Range Descriptor
+ EArmObjCpcInfo, ///< 42 - Continuous Performance Control Info
EArmObjMax
} EARM_OBJECT_ID;

@@ -97,99 +98,105 @@ typedef struct CmArmPowerManagementProfileInfo {
*/
typedef struct CmArmGicCInfo {
/// The GIC CPU Interface number.
- UINT32 CPUInterfaceNumber;
+ UINT32 CPUInterfaceNumber;

/** The ACPI Processor UID. This must match the
_UID of the CPU Device object information described
in the DSDT/SSDT for the CPU.
*/
- UINT32 AcpiProcessorUid;
+ UINT32 AcpiProcessorUid;

/** The flags field as described by the GICC structure
in the ACPI Specification.
*/
- UINT32 Flags;
+ UINT32 Flags;

/** The parking protocol version field as described by
the GICC structure in the ACPI Specification.
*/
- UINT32 ParkingProtocolVersion;
+ UINT32 ParkingProtocolVersion;

/** The Performance Interrupt field as described by
the GICC structure in the ACPI Specification.
*/
- UINT32 PerformanceInterruptGsiv;
+ UINT32 PerformanceInterruptGsiv;

/** The CPU Parked address field as described by
the GICC structure in the ACPI Specification.
*/
- UINT64 ParkedAddress;
+ UINT64 ParkedAddress;

/** The base address for the GIC CPU Interface
as described by the GICC structure in the
ACPI Specification.
*/
- UINT64 PhysicalBaseAddress;
+ UINT64 PhysicalBaseAddress;

/** The base address for GICV interface
as described by the GICC structure in the
ACPI Specification.
*/
- UINT64 GICV;
+ UINT64 GICV;

/** The base address for GICH interface
as described by the GICC structure in the
ACPI Specification.
*/
- UINT64 GICH;
+ UINT64 GICH;

/** The GICV maintenance interrupt
as described by the GICC structure in the
ACPI Specification.
*/
- UINT32 VGICMaintenanceInterrupt;
+ UINT32 VGICMaintenanceInterrupt;

/** The base address for GICR interface
as described by the GICC structure in the
ACPI Specification.
*/
- UINT64 GICRBaseAddress;
+ UINT64 GICRBaseAddress;

/** The MPIDR for the CPU
as described by the GICC structure in the
ACPI Specification.
*/
- UINT64 MPIDR;
+ UINT64 MPIDR;

/** The Processor Power Efficiency class
as described by the GICC structure in the
ACPI Specification.
*/
- UINT8 ProcessorPowerEfficiencyClass;
+ UINT8 ProcessorPowerEfficiencyClass;

/** Statistical Profiling Extension buffer overflow GSIV. Zero if
unsupported by this processor. This field was introduced in
ACPI 6.3 (MADT revision 5) and is therefore ignored when
generating MADT revision 4 or lower.
*/
- UINT16 SpeOverflowInterrupt;
+ UINT16 SpeOverflowInterrupt;

/** The proximity domain to which the logical processor belongs.
This field is used to populate the GICC affinity structure
in the SRAT table.
*/
- UINT32 ProximityDomain;
+ UINT32 ProximityDomain;

/** The clock domain to which the logical processor belongs.
This field is used to populate the GICC affinity structure
in the SRAT table.
*/
- UINT32 ClockDomain;
+ UINT32 ClockDomain;

/** The GICC Affinity flags field as described by the GICC Affinity structure
in the SRAT table.
*/
- UINT32 AffinityFlags;
+ UINT32 AffinityFlags;
+
+ /** Optional field: Reference Token for the Cpc info of this processor.
+ Token identifying a CM_ARM_OBJ_REF structure, itself referencing
+ CM_ARM_CPC_INFO objects.
+ */
+ CM_OBJECT_TOKEN CpcToken;
} CM_ARM_GICC_INFO;

/** A structure that describes the
@@ -1070,6 +1077,113 @@ typedef struct CmArmRmrDescriptor {
UINT64 Length;
} CM_ARM_MEMORY_RANGE_DESCRIPTOR;

+/** A structure that describes the Cpc information.
+
+ Continuous Performance Control is described in DSDT/SSDT and associated
+ to cpus/clusters in the cpu topology.
+
+ Unsupported Optional registers should be encoded with NULL resource
+ Register {(SystemMemory, 0, 0, 0, 0)}
+
+ For values that support Integer or Buffer, integer will be used
+ if buffer is NULL resource.
+ If resource is not NULL then Integer must be 0
+
+ Cf. ACPI 6.4, s8.4.7.1 _CPC (Continuous Performance Control)
+
+ ID: EArmObjCpcInfo
+*/
+typedef struct CmArmCpcInfo {
+ /// The revision number of the _CPC package format.
+ UINT32 Revision;
+
+ /// Indicates the highest level of performance the processor
+ /// is theoretically capable of achieving.
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE HighestPerformanceBuffer;
+ UINT32 HighestPerformanceInteger;
+
+ /// Indicates the highest sustained performance level of the processor.
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE NominalPerformanceBuffer;
+ UINT32 NominalPerformanceInteger;
+
+ /// Indicates the lowest performance level of the processor with non-linear power savings.
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE LowestNonlinearPerformanceBuffer;
+ UINT32 LowestNonlinearPerformanceInteger;
+
+ /// Indicates the lowest performance level of the processor..
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE LowestPerformanceBuffer;
+ UINT32 LowestPerformanceInteger;
+
+ /// Guaranteed Performance Register Buffer.
+ /// Optional
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE GuaranteedPerformanceRegister;
+
+ /// Desired Performance Register Buffer.
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE DesiredPerformanceRegister;
+
+ /// Minimum Performance Register Buffer.
+ /// Optional
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE MinimumPerformanceRegister;
+
+ /// Maximum Performance Register Buffer.
+ /// Optional
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE MaximumPerformanceRegister;
+
+ /// Performance Reduction Tolerance Register.
+ /// Optional
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE PerformanceReductionToleranceRegister;
+
+ /// Time Window Register.
+ /// Optional
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE TimeWindowRegister;
+
+ /// Counter Wraparound Time
+ /// Optional
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE CounterWraparoundTimeBuffer;
+ UINT32 CounterWraparoundTimeInteger;
+
+ /// Reference Performance Counter Register
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE ReferencePerformanceCounterRegister;
+
+ /// Delivered Performance Counter Register
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE DeliveredPerformanceCounterRegister;
+
+ /// Performance Limited Register
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE PerformanceLimitedRegister;
+
+ /// CPPC EnableRegister
+ /// Optional
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE CPPCEnableRegister;
+
+ /// Autonomous Selection Enable
+ /// Optional
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE AutonomousSelectionEnableBuffer;
+ UINT32 AutonomousSelectionEnableInteger;
+
+ /// AutonomousActivity-WindowRegister
+ /// Optional
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE AutonomousActivityWindowRegister;
+
+ /// EnergyPerformance-PreferenceRegister
+ /// Optional
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE EnergyPerformancePreferenceRegister;
+
+ /// Reference Performance
+ /// Optional
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE ReferencePerformanceBuffer;
+ UINT32 ReferencePerformanceInteger;
+
+ /// Lowest Frequency
+ /// Optional
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE LowestFrequencyBuffer;
+ UINT32 LowestFrequencyInteger;
+
+ /// Nominal Frequency
+ /// Optional
+ EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE NominalFrequencyBuffer;
+ UINT32 NominalFrequencyInteger;
+} CM_ARM_CPC_INFO;
+
#pragma pack()

#endif // ARM_NAMESPACE_OBJECTS_H_
diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
index c1b21d24a4..e2c608443b 100644
--- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
+++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
@@ -423,6 +423,83 @@ STATIC CONST CM_OBJ_PARSER CmPciInterruptMapInfoParser[] = {
ARRAY_SIZE (CmArmGenericInterruptParser) },
};

+/** A parser for EArmObjCpcInfo.
+*/
+STATIC CONST CM_OBJ_PARSER CmArmCpcInfoParser[] = {
+ { "HighestPerformanceBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "HighestPerformanceInteger", 4, "0x%llx", NULL },
+ { "NominalPerformanceBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "NominalPerformanceInteger", 4, "0x%llx", NULL },
+ { "LowestNonlinearPerformanceBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "LowestNonlinearPerformanceInteger", 4, "0x%llx", NULL },
+ { "LowestPerformanceBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "LowestPerformanceInteger", 4, "0x%llx", NULL },
+ { "GuaranteedPerformanceRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "DesiredPerformanceRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "MinimumPerformanceRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "MaximumPerformanceRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "PerformanceReductionToleranceRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "TimeWindowRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "CounterWraparoundTimeBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "CounterWraparoundTimeInteger", 4, "0x%llx", NULL },
+ { "ReferencePerformanceCounterRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "DeliveredPerformanceCounterRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "PerformanceLimitedRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "CPPCEnableRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "AutonomousSelectionEnableBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "AutonomousSelectionEnableInteger", 4, "0x%llx", NULL },
+ { "AutonomousActivityWindowRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "EnergyPerformancePreferenceRegister", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "ReferencePerformanceBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "ReferencePerformanceInteger", 4, "0x%llx", NULL },
+ { "LowestFrequencyBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "LowestFrequencyInteger", 4, "0x%llx", NULL },
+ { "NominalFrequencyBuffer", sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser,
+ ARRAY_SIZE (AcpiGenericAddressParser) },
+ { "NominalFrequencyInteger", 4, "0x%llx", NULL },
+};
+
/** A parser for Arm namespace objects.
*/
STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = {
@@ -501,6 +578,8 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArmNamespaceObjectParser[] = {
ARRAY_SIZE (CmArmPciAddressMapInfoParser) },
{ "EArmObjPciInterruptMapInfo", CmPciInterruptMapInfoParser,
ARRAY_SIZE (CmPciInterruptMapInfoParser) },
+ { "EArmObjCpcInfo", CmArmCpcInfoParser,
+ ARRAY_SIZE (CmArmCpcInfoParser) },
{ "EArmObjMax", NULL, 0 },
};

--
2.25.1


[PATCH v2 3/3] DynamicTablesPkg: SSDT CPU _CPC generator

Jeff Brasen
 

Add code to use a token attached to GICC to generate _CPC object on cpus.

Signed-off-by: Jeff Brasen <jbrasen@...>
---
.../SsdtCpuTopologyGenerator.c | 223 +++++++++++++++++-
1 file changed, 217 insertions(+), 6 deletions(-)

diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c
index 8561f48e1f..56741e7b58 100644
--- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCpuTopologyLibArm/SsdtCpuTopologyGenerator.c
@@ -76,6 +76,16 @@ GET_OBJECT_LIST (
CM_ARM_LPI_INFO
);

+/**
+ This macro expands to a function that retrieves the CPC
+ information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjCpcInfo,
+ CM_ARM_CPC_INFO
+ );
+
/** Initialize the TokenTable.

One entry should be allocated for each CM_ARM_PROC_HIERARCHY_INFO
@@ -229,6 +239,183 @@ WriteAslName (
return EFI_SUCCESS;
}

+/** Utility function to check if generic address points to NULL
+
+ @param [in] Address Pointer to the Generic address
+
+ @retval TRUE Address is system memory with an Address of 0.
+ @retval FALSE Address does not point to NULL.
+**/
+STATIC
+BOOLEAN
+EFIAPI
+IsNullGenericAddress (
+ IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE *Address
+ )
+{
+ if ((Address == NULL) ||
+ ((Address->AddressSpaceId == EFI_ACPI_6_4_SYSTEM_MEMORY) &&
+ (Address->Address == 0x0)))
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/** Create and add an _CPC Node to Cpu Node.
+
+ For instance, transform an AML node from:
+ Device (C002)
+ {
+ Name (_UID, 2)
+ Name (_HID, "ACPI0007")
+ }
+
+ To:
+ Device (C002)
+ {
+ Name (_UID, 2)
+ Name (_HID, "ACPI0007")
+ Name(_CPC, Package()
+ {
+ NumEntries, // Integer
+ Revision, // Integer
+ HighestPerformance, // Integer or Buffer (Resource Descriptor)
+ NominalPerformance, // Integer or Buffer (Resource Descriptor)
+ LowestNonlinearPerformance, // Integer or Buffer (Resource Descriptor)
+ LowestPerformance, // Integer or Buffer (Resource Descriptor)
+ GuaranteedPerformanceRegister, // Buffer (Resource Descriptor)
+ DesiredPerformanceRegister , // Buffer (Resource Descriptor)
+ MinimumPerformanceRegister , // Buffer (Resource Descriptor)
+ MaximumPerformanceRegister , // Buffer (Resource Descriptor)
+ PerformanceReductionToleranceRegister, // Buffer (Resource Descriptor)
+ TimeWindowRegister, // Buffer (Resource Descriptor)
+ CounterWraparoundTime, // Integer or Buffer (Resource Descriptor)
+ ReferencePerformanceCounterRegister, // Buffer (Resource Descriptor)
+ DeliveredPerformanceCounterRegister, // Buffer (Resource Descriptor)
+ PerformanceLimitedRegister, // Buffer (Resource Descriptor)
+ CPPCEnableRegister // Buffer (Resource Descriptor)
+ AutonomousSelectionEnable, // Integer or Buffer (Resource Descriptor)
+ AutonomousActivityWindowRegister, // Buffer (Resource Descriptor)
+ EnergyPerformancePreferenceRegister, // Buffer (Resource Descriptor)
+ ReferencePerformance // Integer or Buffer (Resource Descriptor)
+ LowestFrequency, // Integer or Buffer (Resource Descriptor)
+ NominalFrequency // Integer or Buffer (Resource Descriptor)
+ })
+ }
+
+ @param [in] Generator The SSDT Cpu Topology generator.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] ProcHierarchyNodeInfo CM_ARM_PROC_HIERARCHY_INFO describing
+ the Cpu.
+ @param [in] Node CPU Node to which the _CPC node is
+ attached.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CreateAmlCpcNode (
+ IN ACPI_CPU_TOPOLOGY_GENERATOR *Generator,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
+ IN CM_ARM_GICC_INFO *GicCInfo,
+ IN AML_OBJECT_NODE_HANDLE *Node
+ )
+{
+ EFI_STATUS Status;
+ CM_ARM_CPC_INFO *CpcInfo;
+
+ Status = GetEArmObjCpcInfo (
+ CfgMgrProtocol,
+ GicCInfo->CpcToken,
+ &CpcInfo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (0);
+ return Status;
+ }
+
+ Status = AmlCreateCpcNode (
+ CpcInfo->Revision,
+ IsNullGenericAddress (&CpcInfo->HighestPerformanceBuffer) ?
+ NULL :
+ &CpcInfo->HighestPerformanceBuffer,
+ CpcInfo->HighestPerformanceInteger,
+ IsNullGenericAddress (&CpcInfo->NominalPerformanceBuffer) ?
+ NULL :
+ &CpcInfo->NominalPerformanceBuffer,
+ CpcInfo->NominalPerformanceInteger,
+ IsNullGenericAddress (&CpcInfo->LowestNonlinearPerformanceBuffer) ?
+ NULL :
+ &CpcInfo->LowestNonlinearPerformanceBuffer,
+ CpcInfo->LowestNonlinearPerformanceInteger,
+ IsNullGenericAddress (&CpcInfo->LowestPerformanceBuffer) ?
+ NULL :
+ &CpcInfo->LowestPerformanceBuffer,
+ CpcInfo->LowestPerformanceInteger,
+ IsNullGenericAddress (&CpcInfo->GuaranteedPerformanceRegister) ?
+ NULL :
+ &CpcInfo->GuaranteedPerformanceRegister,
+ IsNullGenericAddress (&CpcInfo->DesiredPerformanceRegister) ?
+ NULL :
+ &CpcInfo->DesiredPerformanceRegister,
+ IsNullGenericAddress (&CpcInfo->MinimumPerformanceRegister) ?
+ NULL :
+ &CpcInfo->MinimumPerformanceRegister,
+ IsNullGenericAddress (&CpcInfo->MaximumPerformanceRegister) ?
+ NULL :
+ &CpcInfo->MaximumPerformanceRegister,
+ IsNullGenericAddress (&CpcInfo->PerformanceReductionToleranceRegister) ?
+ NULL :
+ &CpcInfo->PerformanceReductionToleranceRegister,
+ IsNullGenericAddress (&CpcInfo->TimeWindowRegister) ?
+ NULL :
+ &CpcInfo->TimeWindowRegister,
+ IsNullGenericAddress (&CpcInfo->CounterWraparoundTimeBuffer) ?
+ NULL :
+ &CpcInfo->CounterWraparoundTimeBuffer,
+ CpcInfo->CounterWraparoundTimeInteger,
+ &CpcInfo->ReferencePerformanceCounterRegister,
+ &CpcInfo->DeliveredPerformanceCounterRegister,
+ &CpcInfo->PerformanceLimitedRegister,
+ IsNullGenericAddress (&CpcInfo->CPPCEnableRegister) ?
+ NULL :
+ &CpcInfo->CPPCEnableRegister,
+ IsNullGenericAddress (&CpcInfo->AutonomousSelectionEnableBuffer) ?
+ NULL :
+ &CpcInfo->AutonomousSelectionEnableBuffer,
+ CpcInfo->AutonomousSelectionEnableInteger,
+ IsNullGenericAddress (&CpcInfo->AutonomousActivityWindowRegister) ?
+ NULL :
+ &CpcInfo->AutonomousActivityWindowRegister,
+ IsNullGenericAddress (&CpcInfo->EnergyPerformancePreferenceRegister) ?
+ NULL :
+ &CpcInfo->EnergyPerformancePreferenceRegister,
+ IsNullGenericAddress (&CpcInfo->ReferencePerformanceBuffer) ?
+ NULL :
+ &CpcInfo->ReferencePerformanceBuffer,
+ CpcInfo->ReferencePerformanceInteger,
+ IsNullGenericAddress (&CpcInfo->LowestFrequencyBuffer) ?
+ NULL :
+ &CpcInfo->LowestFrequencyBuffer,
+ CpcInfo->LowestFrequencyInteger,
+ IsNullGenericAddress (&CpcInfo->NominalFrequencyBuffer) ?
+ NULL :
+ &CpcInfo->NominalFrequencyBuffer,
+ CpcInfo->NominalFrequencyInteger,
+ Node,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
+
/** Create and add an _LPI method to Cpu/Cluster Node.

For instance, transform an AML node from:
@@ -581,7 +768,20 @@ CreateAmlCpuFromProcHierarchy (
// CM_ARM_PROC_HIERARCHY_INFO, create an _LPI method returning them.
if (ProcHierarchyNodeInfo->LpiToken != CM_NULL_TOKEN) {
Status = CreateAmlLpiMethod (Generator, ProcHierarchyNodeInfo, CpuNode);
- ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+ }
+
+ // If a CPC info is associated with the
+ // GicCinfo, create an _CPC method returning them.
+ if (GicCInfo->CpcToken != CM_NULL_TOKEN) {
+ Status = CreateAmlCpcNode (Generator, CfgMgrProtocol, GicCInfo, CpuNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
}

return Status;
@@ -934,10 +1134,11 @@ CreateTopologyFromGicC (
IN AML_OBJECT_NODE_HANDLE ScopeNode
)
{
- EFI_STATUS Status;
- CM_ARM_GICC_INFO *GicCInfo;
- UINT32 GicCInfoCount;
- UINT32 Index;
+ EFI_STATUS Status;
+ CM_ARM_GICC_INFO *GicCInfo;
+ UINT32 GicCInfoCount;
+ UINT32 Index;
+ AML_OBJECT_NODE_HANDLE CpuNode;

ASSERT (Generator != NULL);
ASSERT (CfgMgrProtocol != NULL);
@@ -961,12 +1162,22 @@ CreateTopologyFromGicC (
ScopeNode,
&GicCInfo[Index],
Index,
- NULL
+ &CpuNode
);
if (EFI_ERROR (Status)) {
ASSERT (0);
break;
}
+
+ // If a CPC info is associated with the
+ // GicCinfo, create an _CPC method returning them.
+ if (GicCInfo->CpcToken != CM_NULL_TOKEN) {
+ Status = CreateAmlCpcNode (Generator, CfgMgrProtocol, &GicCInfo[Index], CpuNode);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+ }
} // for

return Status;
--
2.25.1


[PATCH v2 0/3] DynamicTablesPkg: _CPC support

Jeff Brasen
 

Add generator for creating the _CPC object for CPU nodes.

If viewing this review by a pull request is helpful one exists here:
https://github.com/NVIDIA/edk2/pull/12

Change Log:
v1 - Initial Revision
v2 - Added revision to object, improved error handling, changed to ACPI 6.4 structures.

Jeff Brasen (3):
DynamicTablesPkg: Add CM_ARM_CPC_INFO object
DynamicTablesPkg: AML Code generation to add _CPC entries
DynamicTablesPkg: SSDT CPU _CPC generator

.../Include/ArmNameSpaceObjects.h | 148 ++++-
.../Include/Library/AmlLib/AmlLib.h | 156 +++++
.../SsdtCpuTopologyGenerator.c | 223 ++++++-
.../Common/AmlLib/CodeGen/AmlCodeGen.c | 543 ++++++++++++++++++
.../ConfigurationManagerObjectParser.c | 79 +++
5 files changed, 1126 insertions(+), 23 deletions(-)

--
2.25.1


[PATCH v6 1/1] NetworkPkg/HttpBootDxe: Add Support for HTTPS Proxy Server for HTTP Boot

Saloni Kasbekar
 

Add CONNECT HTTP command to create a tunnel from Proxy to EndPoint Server.
Add support to connect through proxy server using multi-URI DevicePath
sent to the Boot Manager.

Cc: Maciej Rabeda <maciej.rabeda@...>
Cc: Wu Jiaxin <jiaxin.wu@...>
Cc: Siyuan Fu <siyuan.fu@...>
Cc: Jian J Wang <jian.j.wang@...>
Cc: Liming Gao <gaoliming@...>
Signed-off-by: Saloni Kasbekar <saloni.kasbekar@...>
---
.../Library/UefiBootManagerLib/BmBoot.c | 28 +++
.../UefiBootManagerLib/BmBootDescription.c | 4 +-
MdePkg/Include/Protocol/Http.h | 5 +
NetworkPkg/HttpBootDxe/HttpBootClient.c | 222 +++++++++++++++++-
NetworkPkg/HttpBootDxe/HttpBootClient.h | 15 ++
NetworkPkg/HttpBootDxe/HttpBootDxe.h | 6 +
NetworkPkg/HttpBootDxe/HttpBootImpl.c | 211 ++++++++++++-----
NetworkPkg/HttpBootDxe/HttpBootImpl.h | 8 +
NetworkPkg/HttpBootDxe/HttpBootSupport.c | 18 +-
NetworkPkg/HttpBootDxe/HttpBootSupport.h | 8 +-
NetworkPkg/HttpDxe/HttpDriver.h | 2 +
NetworkPkg/HttpDxe/HttpDxe.inf | 1 +
NetworkPkg/HttpDxe/HttpImpl.c | 139 +++++++++--
NetworkPkg/HttpDxe/HttpProto.c | 41 ++--
NetworkPkg/HttpDxe/HttpProto.h | 14 +-
NetworkPkg/HttpDxe/HttpsSupport.c | 14 +-
NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c | 5 +
17 files changed, 631 insertions(+), 110 deletions(-)

diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
index 962892d38f14..fdef1ba292e2 100644
--- a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
+++ b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
@@ -1513,6 +1513,9 @@ BmExpandLoadFiles (
UINTN HandleCount;
UINTN Index;
EFI_DEVICE_PATH_PROTOCOL *Node;
+ URI_DEVICE_PATH *NullUriPath;
+
+ NullUriPath = NULL;

//
// Get file buffer from load file instance.
@@ -1545,11 +1548,36 @@ BmExpandLoadFiles (

for (Index = 0; Index < HandleCount; Index++) {
if (BmMatchHttpBootDevicePath (DevicePathFromHandle (Handles[Index]), FilePath)) {
+ //
+ // Matches HTTP Boot Device Path described as
+ // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv4(...)[/Dns(...)]/Uri(...)
+ // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv6(...)[/Dns(...)]/Uri(...)
+ //
+ Handle = Handles[Index];
+ goto Done;
+ }
+ }
+
+ NullUriPath = (URI_DEVICE_PATH *)CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_URI_DP,
+ (UINT16)(sizeof (URI_DEVICE_PATH))
+ );
+ for (Index = 0; Index < HandleCount; Index++) {
+ if (BmMatchHttpBootDevicePath (AppendDevicePathNode (DevicePathFromHandle (Handles[Index]), (EFI_DEVICE_PATH_PROTOCOL *)NullUriPath), FilePath)) {
+ //
+ // Matches HTTP Boot Device Path described as
+ // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv4(...)[/Dns(...)]/Uri(...)/Uri(...)
+ // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv6(...)[/Dns(...)]/Uri(...)/Uri(...)
+ //
Handle = Handles[Index];
break;
}
}

+ FreePool (NullUriPath);
+
+Done:
if (Handles != NULL) {
FreePool (Handles);
}
diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmBootDescription.c b/MdeModulePkg/Library/UefiBootManagerLib/BmBootDescription.c
index fac33b9ee915..19b7cd14575f 100644
--- a/MdeModulePkg/Library/UefiBootManagerLib/BmBootDescription.c
+++ b/MdeModulePkg/Library/UefiBootManagerLib/BmBootDescription.c
@@ -412,8 +412,8 @@ BmGetNetworkDescription (
// ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv6(...)
//
// The HTTP device path is like:
- // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv4(...)[/Dns(...)]/Uri(...)
- // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv6(...)[/Dns(...)]/Uri(...)
+ // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv4(...)[/Dns(...)]/Uri(...)[/Uri(...)]
+ // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv6(...)[/Dns(...)]/Uri(...)[/Uri(...)]
//
while (!IsDevicePathEnd (DevicePath) &&
((DevicePathType (DevicePath) != MESSAGING_DEVICE_PATH) ||
diff --git a/MdePkg/Include/Protocol/Http.h b/MdePkg/Include/Protocol/Http.h
index 28e622159392..d47092c58e5a 100644
--- a/MdePkg/Include/Protocol/Http.h
+++ b/MdePkg/Include/Protocol/Http.h
@@ -191,6 +191,11 @@ typedef struct {
/// is assumed. See RFC 3986 for more details on URI syntax.
///
CHAR16 *Url;
+ ///
+ /// The URI of an endpoint host if the Url field contains the address of a proxy server.
+ /// This field will be NULL there is no proxy server in the device path.
+ ///
+ CHAR16 *EndPointUrl;
} EFI_HTTP_REQUEST_DATA;

///
diff --git a/NetworkPkg/HttpBootDxe/HttpBootClient.c b/NetworkPkg/HttpBootDxe/HttpBootClient.c
index 40f64fcb6bf8..f8ff5d0e8956 100644
--- a/NetworkPkg/HttpBootDxe/HttpBootClient.c
+++ b/NetworkPkg/HttpBootDxe/HttpBootClient.c
@@ -678,6 +678,10 @@ HttpBootFreeCache (
FreePool (Cache->RequestData->Url);
}

+ if (Cache->RequestData->EndPointUrl != NULL) {
+ FreePool (Cache->RequestData->EndPointUrl);
+ }
+
FreePool (Cache->RequestData);
}

@@ -901,6 +905,200 @@ HttpBootGetBootFileCallback (
return EFI_SUCCESS;
}

+/**
+ This function establishes a connection through a proxy server
+
+ @param[in] Private The pointer to the driver's private data.
+
+ @retval EFI_SUCCESS Connection successful.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources
+ @retval Others Unexpected error happened.
+
+**/
+EFI_STATUS
+HttpBootConnectProxy (
+ IN HTTP_BOOT_PRIVATE_DATA *Private
+ )
+{
+ EFI_STATUS Status;
+ EFI_HTTP_STATUS_CODE StatusCode;
+ CHAR8 *HostName;
+ EFI_HTTP_REQUEST_DATA *RequestData;
+ HTTP_IO_RESPONSE_DATA *ResponseData;
+ HTTP_IO *HttpIo;
+ HTTP_IO_HEADER *HttpIoHeader;
+ CHAR16 *Url;
+ CHAR16 *EndPointUrl;
+ UINTN UrlSize;
+ VOID *UrlParser;
+
+ UrlSize = AsciiStrSize (Private->BootFileUri);
+ Url = AllocatePool (UrlSize * sizeof (CHAR16));
+ if (Url == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ AsciiStrToUnicodeStrS (Private->BootFileUri, Url, UrlSize);
+
+ UrlSize = AsciiStrSize (Private->EndPointUri);
+ EndPointUrl = AllocatePool (UrlSize * (sizeof (CHAR16)));
+ if (EndPointUrl == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ERROR_1;
+ }
+
+ AsciiStrToUnicodeStrS (Private->EndPointUri, EndPointUrl, UrlSize);
+
+ //
+ // Send HTTP request message.
+ //
+
+ //
+ // Build HTTP header for the request, 2 headers are needed to send a CONNECT method:
+ // Host
+ // User
+ //
+ HttpIoHeader = HttpIoCreateHeader (2);
+ if (HttpIoHeader == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ERROR_2;
+ }
+
+ //
+ // Add HTTP header field 1: Host (EndPoint URI)
+ //
+ Status = HttpParseUrl (Private->EndPointUri, (UINT32)AsciiStrLen (Private->EndPointUri), FALSE, &UrlParser);
+ if (EFI_ERROR (Status)) {
+ goto ERROR_2;
+ }
+
+ Status = HttpUrlGetHostName (
+ Private->EndPointUri,
+ UrlParser,
+ &HostName
+ );
+ if (EFI_ERROR (Status)) {
+ goto ERROR_2;
+ }
+
+ Status = HttpIoSetHeader (
+ HttpIoHeader,
+ HTTP_HEADER_HOST,
+ HostName
+ );
+ if (EFI_ERROR (Status)) {
+ goto ERROR_2;
+ }
+
+ //
+ // Add HTTP header field 2: User-Agent
+ //
+ Status = HttpIoSetHeader (
+ HttpIoHeader,
+ HTTP_HEADER_USER_AGENT,
+ HTTP_USER_AGENT_EFI_HTTP_BOOT
+ );
+ if (EFI_ERROR (Status)) {
+ goto ERROR_2;
+ }
+
+ //
+ // Build the rest of HTTP request info.
+ //
+ RequestData = AllocatePool (sizeof (EFI_HTTP_REQUEST_DATA));
+ if (RequestData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ERROR_2;
+ }
+
+ RequestData->Method = HttpMethodConnect;
+ RequestData->Url = Url;
+ RequestData->EndPointUrl = EndPointUrl;
+
+ //
+ // Send out the request to HTTP server.
+ //
+ HttpIo = &Private->HttpIo;
+ Status = HttpIoSendRequest (
+ HttpIo,
+ RequestData,
+ HttpIoHeader->HeaderCount,
+ HttpIoHeader->Headers,
+ 0,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ goto ERROR_3;
+ }
+
+ //
+ // Receive HTTP response message.
+ //
+
+ //
+ // Use zero BodyLength to only receive the response headers.
+ //
+ ResponseData = AllocateZeroPool (sizeof (HTTP_IO_RESPONSE_DATA));
+ if (ResponseData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ERROR_3;
+ }
+
+ Status = HttpIoRecvResponse (
+ &Private->HttpIo,
+ TRUE,
+ ResponseData
+ );
+
+ if (EFI_ERROR (Status) || EFI_ERROR (ResponseData->Status)) {
+ if (EFI_ERROR (ResponseData->Status)) {
+ StatusCode = HttpIo->RspToken.Message->Data.Response->StatusCode;
+ HttpBootPrintErrorMessage (StatusCode);
+ Status = ResponseData->Status;
+ }
+
+ goto ERROR_4;
+ }
+
+ if (EndPointUrl != NULL) {
+ FreePool (EndPointUrl);
+ }
+
+ if (ResponseData != NULL) {
+ FreePool (ResponseData);
+ }
+
+ if (RequestData != NULL) {
+ FreePool (RequestData);
+ }
+
+ return Status;
+
+ERROR_4:
+ if (ResponseData != NULL) {
+ FreePool (ResponseData);
+ }
+
+ERROR_3:
+ if (RequestData != NULL) {
+ FreePool (RequestData);
+ }
+
+ERROR_2:
+ HttpIoFreeHeader (HttpIoHeader);
+
+ERROR_1:
+ if (EndPointUrl != NULL) {
+ FreePool (EndPointUrl);
+ }
+
+ if (Url != NULL) {
+ FreePool (Url);
+ }
+
+ return Status;
+}
+
/**
This function download the boot file by using UEFI HTTP protocol.

@@ -950,6 +1148,7 @@ HttpBootGetBootFile (
UINT8 *Block;
UINTN UrlSize;
CHAR16 *Url;
+ CHAR16 *EndPointUrl;
BOOLEAN IdentityMode;
UINTN ReceivedSize;
CHAR8 BaseAuthValue[80];
@@ -977,6 +1176,20 @@ HttpBootGetBootFile (
}

AsciiStrToUnicodeStrS (Private->BootFileUri, Url, UrlSize);
+
+ if (Private->EndPointUri != NULL) {
+ UrlSize = AsciiStrSize (Private->EndPointUri);
+ EndPointUrl = AllocatePool (UrlSize * (sizeof (CHAR16)));
+ if (EndPointUrl == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ERROR_1;
+ }
+
+ AsciiStrToUnicodeStrS (Private->EndPointUri, EndPointUrl, UrlSize);
+ } else {
+ EndPointUrl = NULL;
+ }
+
if (!HeaderOnly && (Buffer != NULL)) {
Status = HttpBootGetFileFromCache (Private, Url, BufferSize, Buffer, ImageType);
if (Status != EFI_NOT_FOUND) {
@@ -1106,8 +1319,9 @@ HttpBootGetBootFile (
goto ERROR_3;
}

- RequestData->Method = HeaderOnly ? HttpMethodHead : HttpMethodGet;
- RequestData->Url = Url;
+ RequestData->Method = HeaderOnly ? HttpMethodHead : HttpMethodGet;
+ RequestData->Url = Url;
+ RequestData->EndPointUrl = EndPointUrl;

//
// 2.3 Record the request info in a temp cache item.
@@ -1441,6 +1655,10 @@ ERROR_2:
}

ERROR_1:
+ if (EndPointUrl != NULL) {
+ FreePool (EndPointUrl);
+ }
+
if (Url != NULL) {
FreePool (Url);
}
diff --git a/NetworkPkg/HttpBootDxe/HttpBootClient.h b/NetworkPkg/HttpBootDxe/HttpBootClient.h
index 2fba71367950..fcd624f536a3 100644
--- a/NetworkPkg/HttpBootDxe/HttpBootClient.h
+++ b/NetworkPkg/HttpBootDxe/HttpBootClient.h
@@ -86,6 +86,21 @@ HttpBootCreateHttpIo (
IN HTTP_BOOT_PRIVATE_DATA *Private
);

+/**
+ This function establishes a connection through a proxy server
+
+ @param[in] Private The pointer to the driver's private data.
+
+ @retval EFI_SUCCESS Connection successful.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources
+ @retval Others Unexpected error happened.
+
+**/
+EFI_STATUS
+HttpBootConnectProxy (
+ IN HTTP_BOOT_PRIVATE_DATA *Private
+ );
+
/**
This function download the boot file by using UEFI HTTP protocol.

diff --git a/NetworkPkg/HttpBootDxe/HttpBootDxe.h b/NetworkPkg/HttpBootDxe/HttpBootDxe.h
index 5ff8ad4698b2..e2eb1ffc4544 100644
--- a/NetworkPkg/HttpBootDxe/HttpBootDxe.h
+++ b/NetworkPkg/HttpBootDxe/HttpBootDxe.h
@@ -223,6 +223,12 @@ struct _HTTP_BOOT_PRIVATE_DATA {
CHAR8 *FilePathUri;
VOID *FilePathUriParser;

+ //
+ // URI string for the endpoint host if BootFileUri contains a proxy
+ // server in the path
+ //
+ CHAR8 *EndPointUri;
+
//
// Cached HTTP data
//
diff --git a/NetworkPkg/HttpBootDxe/HttpBootImpl.c b/NetworkPkg/HttpBootDxe/HttpBootImpl.c
index b4c61925b94f..d5332f2bac71 100644
--- a/NetworkPkg/HttpBootDxe/HttpBootImpl.c
+++ b/NetworkPkg/HttpBootDxe/HttpBootImpl.c
@@ -116,8 +116,10 @@ HttpBootStart (
UINTN Index;
EFI_STATUS Status;
CHAR8 *Uri;
+ CHAR8 *EndPointUri;

- Uri = NULL;
+ Uri = NULL;
+ EndPointUri = NULL;

if ((Private == NULL) || (FilePath == NULL)) {
return EFI_INVALID_PARAMETER;
@@ -127,7 +129,7 @@ HttpBootStart (
// Check the URI in the input FilePath, in order to see whether it is
// required to boot from a new specified boot file.
//
- Status = HttpBootParseFilePath (FilePath, &Uri);
+ Status = HttpBootParseFilePath (FilePath, &Uri, &EndPointUri);
if (EFI_ERROR (Status)) {
return EFI_INVALID_PARAMETER;
}
@@ -154,6 +156,10 @@ HttpBootStart (
FreePool (Uri);
}

+ if (EndPointUri != NULL) {
+ FreePool (EndPointUri);
+ }
+
return Status;
}
} else {
@@ -164,6 +170,10 @@ HttpBootStart (
FreePool (Uri);
}

+ if (EndPointUri != NULL) {
+ FreePool (EndPointUri);
+ }
+
return EFI_ALREADY_STARTED;
}
}
@@ -180,6 +190,10 @@ HttpBootStart (
FreePool (Uri);
}

+ if (EndPointUri != NULL) {
+ FreePool (EndPointUri);
+ }
+
return EFI_UNSUPPORTED;
}

@@ -187,6 +201,7 @@ HttpBootStart (
// Record the specified URI and prepare the URI parser if needed.
//
Private->FilePathUri = Uri;
+ Private->EndPointUri = EndPointUri;
if (Private->FilePathUri != NULL) {
Status = HttpParseUrl (
Private->FilePathUri,
@@ -274,6 +289,136 @@ HttpBootDhcp (
return Status;
}

+/**
+ Issue calls to HttpBootGetBootFile() based on current Boot File State
+
+ @param[in] Private The pointer to the driver's private data.
+ @param[in, out] BufferSize On input the size of Buffer in bytes. On output with a return
+ code of EFI_SUCCESS, the amount of data transferred to
+ Buffer. On output with a return code of EFI_BUFFER_TOO_SMALL,
+ the size of Buffer required to retrieve the requested file.
+ @param[in] Buffer The memory buffer to transfer the file to. If Buffer is NULL,
+ then the size of the requested file is returned in
+ BufferSize.
+ @param[out] ImageType The image type of the downloaded file.
+
+ @retval EFI_SUCCESS The file was loaded.
+ @retval EFI_INVALID_PARAMETER BufferSize is NULL or Buffer Size is not NULL but Buffer is NULL.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources
+ @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory entry.
+ BufferSize has been updated with the size needed to complete
+ the request.
+ @retval EFI_ACCESS_DENIED Server authentication failed.
+ @retval Others Unexpected error happened.
+
+**/
+EFI_STATUS
+HttpBootGetBootFileCaller (
+ IN HTTP_BOOT_PRIVATE_DATA *Private,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer OPTIONAL,
+ OUT HTTP_BOOT_IMAGE_TYPE *ImageType
+ )
+{
+ HTTP_GET_BOOT_FILE_STATE State;
+ EFI_STATUS Status;
+
+ if (Private->BootFileSize == 0) {
+ if (Private->EndPointUri != NULL) {
+ State = ConnectToProxy;
+ } else {
+ State = GetBootFileHead;
+ }
+ } else {
+ State = LoadBootFile;
+ }
+
+ for ( ; ;) {
+ switch (State) {
+ case GetBootFileHead:
+ //
+ // Try to use HTTP HEAD method.
+ //
+ Status = HttpBootGetBootFile (
+ Private,
+ TRUE,
+ &Private->BootFileSize,
+ NULL,
+ &Private->ImageType
+ );
+ if ((EFI_ERROR (Status)) && (Status != EFI_BUFFER_TOO_SMALL)) {
+ if ((Private->AuthData != NULL) && (Status == EFI_ACCESS_DENIED)) {
+ //
+ // Try to use HTTP HEAD method again since the Authentication information is provided.
+ //
+ State = GetBootFileHead;
+ } else {
+ State = GetBootFileGet;
+ }
+ } else {
+ State = LoadBootFile;
+ }
+
+ break;
+
+ case GetBootFileGet:
+ //
+ // Failed to get file size by HEAD method, may be trunked encoding, try HTTP GET method.
+ //
+ ASSERT (Private->BootFileSize == 0);
+ Status = HttpBootGetBootFile (
+ Private,
+ FALSE,
+ &Private->BootFileSize,
+ NULL,
+ &Private->ImageType
+ );
+ if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
+ State = GetBootFileError;
+ } else {
+ State = LoadBootFile;
+ }
+
+ break;
+
+ case ConnectToProxy:
+ Status = HttpBootConnectProxy (Private);
+ if (Status == EFI_SUCCESS) {
+ State = GetBootFileHead;
+ } else {
+ State = GetBootFileError;
+ }
+
+ break;
+
+ case LoadBootFile:
+ if (*BufferSize < Private->BootFileSize) {
+ *BufferSize = Private->BootFileSize;
+ *ImageType = Private->ImageType;
+ Status = EFI_BUFFER_TOO_SMALL;
+ return Status;
+ }
+
+ //
+ // Load the boot file into Buffer
+ //
+ Status = HttpBootGetBootFile (
+ Private,
+ FALSE,
+ BufferSize,
+ Buffer,
+ ImageType
+ );
+ return Status;
+
+ case GetBootFileError:
+ default:
+ AsciiPrint ("\n Error: Could not retrieve NBP file size from HTTP server.\n");
+ return Status;
+ }
+ }
+}
+
/**
Attempt to download the boot file through HTTP message exchange.

@@ -345,68 +490,10 @@ HttpBootLoadFile (
}
}

- if (Private->BootFileSize == 0) {
- //
- // Discover the information about the bootfile if we haven't.
- //
-
- //
- // Try to use HTTP HEAD method.
- //
- Status = HttpBootGetBootFile (
- Private,
- TRUE,
- &Private->BootFileSize,
- NULL,
- &Private->ImageType
- );
- if ((Private->AuthData != NULL) && (Status == EFI_ACCESS_DENIED)) {
- //
- // Try to use HTTP HEAD method again since the Authentication information is provided.
- //
- Status = HttpBootGetBootFile (
- Private,
- TRUE,
- &Private->BootFileSize,
- NULL,
- &Private->ImageType
- );
- } else if ((EFI_ERROR (Status)) && (Status != EFI_BUFFER_TOO_SMALL)) {
- //
- // Failed to get file size by HEAD method, may be trunked encoding, try HTTP GET method.
- //
- ASSERT (Private->BootFileSize == 0);
- Status = HttpBootGetBootFile (
- Private,
- FALSE,
- &Private->BootFileSize,
- NULL,
- &Private->ImageType
- );
- if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
- AsciiPrint ("\n Error: Could not retrieve NBP file size from HTTP server.\n");
- goto ON_EXIT;
- }
- }
- }
-
- if (*BufferSize < Private->BootFileSize) {
- *BufferSize = Private->BootFileSize;
- *ImageType = Private->ImageType;
- Status = EFI_BUFFER_TOO_SMALL;
- goto ON_EXIT;
- }
-
//
- // Load the boot file into Buffer
+ // Load the Boot File
//
- Status = HttpBootGetBootFile (
- Private,
- FALSE,
- BufferSize,
- Buffer,
- ImageType
- );
+ Status = HttpBootGetBootFileCaller (Private, BufferSize, Buffer, ImageType);

ON_EXIT:
HttpBootUninstallCallback (Private);
diff --git a/NetworkPkg/HttpBootDxe/HttpBootImpl.h b/NetworkPkg/HttpBootDxe/HttpBootImpl.h
index 55adc9cb500f..e4ffc3ed48e5 100644
--- a/NetworkPkg/HttpBootDxe/HttpBootImpl.h
+++ b/NetworkPkg/HttpBootDxe/HttpBootImpl.h
@@ -11,6 +11,14 @@ SPDX-License-Identifier: BSD-2-Clause-Patent

#define HTTP_BOOT_CHECK_MEDIA_WAITING_TIME EFI_TIMER_PERIOD_SECONDS(20)

+typedef enum {
+ GetBootFileHead,
+ GetBootFileGet,
+ ConnectToProxy,
+ LoadBootFile,
+ GetBootFileError
+} HTTP_GET_BOOT_FILE_STATE;
+
/**
Attempt to complete a DHCPv4 D.O.R.A or DHCPv6 S.R.A.A sequence to retrieve the boot resource information.

diff --git a/NetworkPkg/HttpBootDxe/HttpBootSupport.c b/NetworkPkg/HttpBootDxe/HttpBootSupport.c
index 236ef259318b..fddcf8b16746 100644
--- a/NetworkPkg/HttpBootDxe/HttpBootSupport.c
+++ b/NetworkPkg/HttpBootDxe/HttpBootSupport.c
@@ -558,6 +558,7 @@ HttpBootCheckUriScheme (

@param[in] FilePath Pointer to the device path which contains a URI device path node.
@param[out] UriAddress The URI address string extract from the device path.
+ @param[out] EndPointUriAddress The URI address string for the endpoint host if UriAddress contains the address of a proxy server

@retval EFI_SUCCESS The URI string is returned.
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
@@ -566,7 +567,8 @@ HttpBootCheckUriScheme (
EFI_STATUS
HttpBootParseFilePath (
IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
- OUT CHAR8 **UriAddress
+ OUT CHAR8 **UriAddress,
+ OUT CHAR8 **EndPointUriAddress
)
{
EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
@@ -578,8 +580,9 @@ HttpBootParseFilePath (
return EFI_INVALID_PARAMETER;
}

- *UriAddress = NULL;
-
+ Uri = NULL;
+ *UriAddress = NULL;
+ *EndPointUriAddress = NULL;
//
// Extract the URI address from the FilePath
//
@@ -601,6 +604,15 @@ HttpBootParseFilePath (
break;
}

+ if (Uri != NULL) {
+ //
+ // Device Path with Proxy Server will be described as
+ // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv4(...)[/Dns(...)]/Uri(EndPointServer)/Uri(ProxyServer/FilePath)
+ // ....../Mac(...)[/Vlan(...)][/Wi-Fi(...)]/IPv6(...)[/Dns(...)]/Uri(EndPointServer)/Uri(ProxyServer/FilePath)
+ //
+ *EndPointUriAddress = Uri;
+ }
+
Uri = AllocatePool (UriStrLength + 1);
if (Uri == NULL) {
return EFI_OUT_OF_RESOURCES;
diff --git a/NetworkPkg/HttpBootDxe/HttpBootSupport.h b/NetworkPkg/HttpBootDxe/HttpBootSupport.h
index 3698e5593642..6228f37e3676 100644
--- a/NetworkPkg/HttpBootDxe/HttpBootSupport.h
+++ b/NetworkPkg/HttpBootDxe/HttpBootSupport.h
@@ -138,8 +138,9 @@ HttpBootCheckUriScheme (

Caller need to free the buffer in the UriAddress pointer.

- @param[in] FilePath Pointer to the device path which contains a URI device path node.
- @param[out] UriAddress The URI address string extract from the device path.
+ @param[in] FilePath Pointer to the device path which contains a URI device path node.
+ @param[out] UriAddress The URI address string extract from the device path.
+ @param[out] EndPointUriAddress The URI address string for the endpoint host if UriAddress contains the address of a proxy server

@retval EFI_SUCCESS The URI string is returned.
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
@@ -148,7 +149,8 @@ HttpBootCheckUriScheme (
EFI_STATUS
HttpBootParseFilePath (
IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
- OUT CHAR8 **UriAddress
+ OUT CHAR8 **UriAddress,
+ OUT CHAR8 **EndPointUriAddress
);

/**
diff --git a/NetworkPkg/HttpDxe/HttpDriver.h b/NetworkPkg/HttpDxe/HttpDriver.h
index 01a6bb7f4b7a..e0917f431e53 100644
--- a/NetworkPkg/HttpDxe/HttpDriver.h
+++ b/NetworkPkg/HttpDxe/HttpDriver.h
@@ -26,6 +26,7 @@
#include <Library/NetLib.h>
#include <Library/HttpLib.h>
#include <Library/DpcLib.h>
+#include <Library/PrintLib.h>

//
// UEFI Driver Model Protocols
@@ -64,6 +65,7 @@
// Driver Version
//
#define HTTP_DRIVER_VERSION 0xa
+#define URI_STR_MAX_SIZE 255

//
// Protocol instances
diff --git a/NetworkPkg/HttpDxe/HttpDxe.inf b/NetworkPkg/HttpDxe/HttpDxe.inf
index c9502d0bb6d0..30b7de1951d1 100644
--- a/NetworkPkg/HttpDxe/HttpDxe.inf
+++ b/NetworkPkg/HttpDxe/HttpDxe.inf
@@ -47,6 +47,7 @@
NetLib
HttpLib
DpcLib
+ PrintLib

[Protocols]
gEfiHttpServiceBindingProtocolGuid ## BY_START
diff --git a/NetworkPkg/HttpDxe/HttpImpl.c b/NetworkPkg/HttpDxe/HttpImpl.c
index 7c5c925cf78b..24ce87fd7d14 100644
--- a/NetworkPkg/HttpDxe/HttpImpl.c
+++ b/NetworkPkg/HttpDxe/HttpImpl.c
@@ -233,35 +233,45 @@ EfiHttpRequest (
EFI_HTTP_MESSAGE *HttpMsg;
EFI_HTTP_REQUEST_DATA *Request;
VOID *UrlParser;
+ VOID *EndPointUrlParser;
EFI_STATUS Status;
CHAR8 *HostName;
+ CHAR8 *EndPointHostName;
UINTN HostNameSize;
UINT16 RemotePort;
+ UINT16 EndPointRemotePort;
HTTP_PROTOCOL *HttpInstance;
BOOLEAN Configure;
BOOLEAN ReConfigure;
BOOLEAN TlsConfigure;
CHAR8 *RequestMsg;
CHAR8 *Url;
+ CHAR8 *EndPointUrl;
UINTN UrlLen;
CHAR16 *HostNameStr;
HTTP_TOKEN_WRAP *Wrap;
CHAR8 *FileUrl;
UINTN RequestMsgSize;
EFI_HANDLE ImageHandle;
+ CHAR8 *EndPointUrlMsg;

//
// Initializations
//
- Url = NULL;
- UrlParser = NULL;
- RemotePort = 0;
- HostName = NULL;
- RequestMsg = NULL;
- HostNameStr = NULL;
- Wrap = NULL;
- FileUrl = NULL;
- TlsConfigure = FALSE;
+ Url = NULL;
+ UrlParser = NULL;
+ EndPointUrlParser = NULL;
+ RemotePort = 0;
+ EndPointRemotePort = 0;
+ HostName = NULL;
+ EndPointHostName = NULL;
+ RequestMsg = NULL;
+ HostNameStr = NULL;
+ Wrap = NULL;
+ FileUrl = NULL;
+ TlsConfigure = FALSE;
+ EndPointUrl = NULL;
+ EndPointUrlMsg = NULL;

if ((This == NULL) || (Token == NULL)) {
return EFI_INVALID_PARAMETER;
@@ -275,16 +285,20 @@ EfiHttpRequest (
Request = HttpMsg->Data.Request;

//
- // Only support GET, HEAD, DELETE, PATCH, PUT and POST method in current implementation.
+ // Only support GET, HEAD, DELETE, PATCH, PUT, CONNECT and POST method in current implementation.
//
if ((Request != NULL) && (Request->Method != HttpMethodGet) &&
(Request->Method != HttpMethodHead) && (Request->Method != HttpMethodDelete) &&
(Request->Method != HttpMethodPut) && (Request->Method != HttpMethodPost) &&
- (Request->Method != HttpMethodPatch))
+ (Request->Method != HttpMethodPatch) && (Request->Method != HttpMethodConnect))
{
return EFI_UNSUPPORTED;
}

+ if ((Request->Method == HttpMethodConnect) && (Request->EndPointUrl == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This);

//
@@ -353,11 +367,25 @@ EfiHttpRequest (

UnicodeStrToAsciiStrS (Request->Url, Url, UrlLen);

+ if (Request->EndPointUrl != NULL) {
+ UrlLen = StrLen (Request->EndPointUrl) + 1;
+ EndPointUrl = AllocateZeroPool (UrlLen);
+ if (EndPointUrl == NULL) {
+ goto Error1;
+ }
+
+ UnicodeStrToAsciiStrS (Request->EndPointUrl, EndPointUrl, UrlLen);
+ }
+
//
// From the information in Url, the HTTP instance will
// be able to determine whether to use http or https.
//
- HttpInstance->UseHttps = IsHttpsUrl (Url);
+ if (HttpInstance->ProxyConnected) {
+ HttpInstance->UseHttps = IsHttpsUrl (EndPointUrl);
+ } else {
+ HttpInstance->UseHttps = IsHttpsUrl (Url);
+ }

//
// HTTP is disabled, return directly if the URI is not HTTPS.
@@ -444,9 +472,10 @@ EfiHttpRequest (
if ((HttpInstance->ConnectionClose == FALSE) &&
(HttpInstance->RemotePort == RemotePort) &&
(AsciiStrCmp (HttpInstance->RemoteHost, HostName) == 0) &&
- (!HttpInstance->UseHttps || (HttpInstance->UseHttps &&
- !TlsConfigure &&
- (HttpInstance->TlsSessionState == EfiTlsSessionDataTransferring))))
+ (!HttpInstance->UseHttps ||
+ HttpInstance->ProxyConnected || (HttpInstance->UseHttps &&
+ !TlsConfigure &&
+ (HttpInstance->TlsSessionState == EfiTlsSessionDataTransferring))))
{
//
// Host Name and port number of the request URL are the same with previous call to Request().
@@ -599,7 +628,7 @@ EfiHttpRequest (
goto Error2;
}

- if (!Configure && !ReConfigure && !TlsConfigure) {
+ if ((!Configure && !ReConfigure) && ((HttpInstance->ProxyConnected && TlsConfigure) || (!TlsConfigure))) {
//
// For the new HTTP token, create TX TCP token events.
//
@@ -632,7 +661,48 @@ EfiHttpRequest (
}
}

- Status = HttpGenRequestMessage (HttpMsg, FileUrl, &RequestMsg, &RequestMsgSize);
+ if (HttpInstance->Method == HttpMethodConnect) {
+ Status = HttpParseUrl (EndPointUrl, (UINT32)AsciiStrLen (EndPointUrl), FALSE, &EndPointUrlParser);
+ if (EFI_ERROR (Status)) {
+ goto Error3;
+ }
+
+ Status = HttpUrlGetHostName (
+ EndPointUrl,
+ EndPointUrlParser,
+ &EndPointHostName
+ );
+ if (EFI_ERROR (Status)) {
+ goto Error3;
+ }
+
+ Status = HttpUrlGetPort (EndPointUrl, EndPointUrlParser, &EndPointRemotePort);
+ if (EFI_ERROR (Status)) {
+ if (IsHttpsUrl (EndPointUrl)) {
+ EndPointRemotePort = HTTPS_DEFAULT_PORT;
+ } else {
+ EndPointRemotePort = HTTP_DEFAULT_PORT;
+ }
+ }
+
+ EndPointUrlMsg = AllocateZeroPool (URI_STR_MAX_SIZE);
+ if (EndPointUrlMsg == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error3;
+ }
+
+ AsciiSPrint (
+ EndPointUrlMsg,
+ URI_STR_MAX_SIZE,
+ "%a:%d",
+ EndPointHostName,
+ EndPointRemotePort
+ );
+
+ Status = HttpGenRequestMessage (HttpMsg, EndPointUrlMsg, &RequestMsg, &RequestMsgSize);
+ } else {
+ Status = HttpGenRequestMessage (HttpMsg, FileUrl, &RequestMsg, &RequestMsgSize);
+ }

if (EFI_ERROR (Status) || (NULL == RequestMsg)) {
goto Error3;
@@ -668,6 +738,23 @@ EfiHttpRequest (

DispatchDpc ();

+ if (HttpInstance->Method == HttpMethodConnect) {
+ HttpInstance->ProxyConnected = TRUE;
+ HttpInstance->EndPointRemoteHost = EndPointHostName;
+
+ if (EndPointUrlParser != NULL) {
+ HttpUrlFreeParser (EndPointUrlParser);
+ }
+ }
+
+ if (EndPointUrlMsg != NULL) {
+ FreePool (EndPointUrlMsg);
+ }
+
+ if (EndPointUrl != NULL) {
+ FreePool (EndPointUrl);
+ }
+
if (HostName != NULL) {
FreePool (HostName);
}
@@ -698,6 +785,20 @@ Error3:
TlsCloseTxRxEvent (HttpInstance);
}

+ if (HttpInstance->Method == HttpMethodConnect) {
+ if (EndPointHostName != NULL) {
+ FreePool (EndPointHostName);
+ }
+
+ if (EndPointUrlParser != NULL) {
+ HttpUrlFreeParser (EndPointUrlParser);
+ }
+ }
+
+ if (EndPointUrlMsg != NULL) {
+ FreePool (EndPointUrlMsg);
+ }
+
Error2:
HttpCloseConnection (HttpInstance);

@@ -725,6 +826,10 @@ Error1:
HttpUrlFreeParser (UrlParser);
}

+ if (EndPointUrl != NULL) {
+ FreePool (EndPointUrl);
+ }
+
return Status;
}

diff --git a/NetworkPkg/HttpDxe/HttpProto.c b/NetworkPkg/HttpDxe/HttpProto.c
index 33ae622c3f0b..b87fbeeb543f 100644
--- a/NetworkPkg/HttpDxe/HttpProto.c
+++ b/NetworkPkg/HttpDxe/HttpProto.c
@@ -849,6 +849,11 @@ HttpCleanProtocol (
HttpInstance->Url = NULL;
}

+ if (HttpInstance->EndPointRemoteHost != NULL) {
+ FreePool (HttpInstance->EndPointRemoteHost);
+ HttpInstance->EndPointRemoteHost = NULL;
+ }
+
NetMapClean (&HttpInstance->TxTokens);
NetMapClean (&HttpInstance->RxTokens);

@@ -1206,6 +1211,7 @@ HttpConfigureTcp6 (
connect one TLS session if required.

@param[in] HttpInstance The HTTP instance private data.
+ @param[in] TlsConfigure The Flag indicates whether it's the new Tls session.

@retval EFI_SUCCESS The TCP connection is established.
@retval EFI_NOT_READY TCP4 protocol child is not created or configured.
@@ -1214,7 +1220,8 @@ HttpConfigureTcp6 (
**/
EFI_STATUS
HttpConnectTcp4 (
- IN HTTP_PROTOCOL *HttpInstance
+ IN HTTP_PROTOCOL *HttpInstance,
+ IN BOOLEAN TlsConfigure
)
{
EFI_STATUS Status;
@@ -1237,16 +1244,18 @@ HttpConnectTcp4 (
return Status;
}

- if (Tcp4State == Tcp4StateEstablished) {
+ if ((Tcp4State == Tcp4StateEstablished) && (!HttpInstance->ProxyConnected || !TlsConfigure)) {
return EFI_SUCCESS;
} else if (Tcp4State > Tcp4StateEstablished ) {
HttpCloseConnection (HttpInstance);
}

- Status = HttpCreateConnection (HttpInstance);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "Tcp4 Connection fail - %x\n", Status));
- return Status;
+ if (!HttpInstance->ProxyConnected) {
+ Status = HttpCreateConnection (HttpInstance);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Tcp4 Connection fail - %x\n", Status));
+ return Status;
+ }
}

//
@@ -1298,6 +1307,7 @@ HttpConnectTcp4 (
connect one TLS session if required.

@param[in] HttpInstance The HTTP instance private data.
+ @param[in] TlsConfigure The Flag indicates whether it's the new Tls session.

@retval EFI_SUCCESS The TCP connection is established.
@retval EFI_NOT_READY TCP6 protocol child is not created or configured.
@@ -1306,7 +1316,8 @@ HttpConnectTcp4 (
**/
EFI_STATUS
HttpConnectTcp6 (
- IN HTTP_PROTOCOL *HttpInstance
+ IN HTTP_PROTOCOL *HttpInstance,
+ IN BOOLEAN TlsConfigure
)
{
EFI_STATUS Status;
@@ -1330,16 +1341,18 @@ HttpConnectTcp6 (
return Status;
}

- if (Tcp6State == Tcp6StateEstablished) {
+ if ((Tcp6State == Tcp6StateEstablished) && (!HttpInstance->ProxyConnected || !TlsConfigure)) {
return EFI_SUCCESS;
} else if (Tcp6State > Tcp6StateEstablished ) {
HttpCloseConnection (HttpInstance);
}

- Status = HttpCreateConnection (HttpInstance);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "Tcp6 Connection fail - %x\n", Status));
- return Status;
+ if (!HttpInstance->ProxyConnected) {
+ Status = HttpCreateConnection (HttpInstance);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Tcp6 Connection fail - %x\n", Status));
+ return Status;
+ }
}

//
@@ -1434,7 +1447,7 @@ HttpInitSession (
//
// Connect TCP.
//
- Status = HttpConnectTcp4 (HttpInstance);
+ Status = HttpConnectTcp4 (HttpInstance, TlsConfigure);
if (EFI_ERROR (Status)) {
return Status;
}
@@ -1452,7 +1465,7 @@ HttpInitSession (
//
// Connect TCP.
//
- Status = HttpConnectTcp6 (HttpInstance);
+ Status = HttpConnectTcp6 (HttpInstance, TlsConfigure);
if (EFI_ERROR (Status)) {
return Status;
}
diff --git a/NetworkPkg/HttpDxe/HttpProto.h b/NetworkPkg/HttpDxe/HttpProto.h
index 620eb3915843..2e8d51635993 100644
--- a/NetworkPkg/HttpDxe/HttpProto.h
+++ b/NetworkPkg/HttpDxe/HttpProto.h
@@ -165,6 +165,12 @@ typedef struct _HTTP_PROTOCOL {

CHAR8 *Url;

+ //
+ // Proxy Server Support
+ //
+ CHAR8 *EndPointRemoteHost;
+ BOOLEAN ProxyConnected;
+
//
// Https Support
//
@@ -398,6 +404,7 @@ HttpConfigureTcp6 (
connect one TLS session if required.

@param[in] HttpInstance The HTTP instance private data.
+ @param[in] TlsConfigure The Flag indicates whether it's the new Tls session.

@retval EFI_SUCCESS The TCP connection is established.
@retval EFI_NOT_READY TCP4 protocol child is not created or configured.
@@ -406,7 +413,8 @@ HttpConfigureTcp6 (
**/
EFI_STATUS
HttpConnectTcp4 (
- IN HTTP_PROTOCOL *HttpInstance
+ IN HTTP_PROTOCOL *HttpInstance,
+ IN BOOLEAN TlsConfigure
);

/**
@@ -414,6 +422,7 @@ HttpConnectTcp4 (
connect one TLS session if required.

@param[in] HttpInstance The HTTP instance private data.
+ @param[in] TlsConfigure The Flag indicates whether it's the new Tls session.

@retval EFI_SUCCESS The TCP connection is established.
@retval EFI_NOT_READY TCP6 protocol child is not created or configured.
@@ -422,7 +431,8 @@ HttpConnectTcp4 (
**/
EFI_STATUS
HttpConnectTcp6 (
- IN HTTP_PROTOCOL *HttpInstance
+ IN HTTP_PROTOCOL *HttpInstance,
+ IN BOOLEAN TlsConfigure
);

/**
diff --git a/NetworkPkg/HttpDxe/HttpsSupport.c b/NetworkPkg/HttpDxe/HttpsSupport.c
index ad611e7c3836..7dc2b752ec47 100644
--- a/NetworkPkg/HttpDxe/HttpsSupport.c
+++ b/NetworkPkg/HttpDxe/HttpsSupport.c
@@ -644,11 +644,15 @@ TlsConfigureSession (
//
// TlsConfigData initialization
//
- HttpInstance->TlsConfigData.ConnectionEnd = EfiTlsClient;
- HttpInstance->TlsConfigData.VerifyMethod = EFI_TLS_VERIFY_PEER;
- HttpInstance->TlsConfigData.VerifyHost.Flags = EFI_TLS_VERIFY_FLAG_NONE;
- HttpInstance->TlsConfigData.VerifyHost.HostName = HttpInstance->RemoteHost;
- HttpInstance->TlsConfigData.SessionState = EfiTlsSessionNotStarted;
+ HttpInstance->TlsConfigData.ConnectionEnd = EfiTlsClient;
+ HttpInstance->TlsConfigData.SessionState = EfiTlsSessionNotStarted;
+ HttpInstance->TlsConfigData.VerifyMethod = EFI_TLS_VERIFY_PEER;
+ HttpInstance->TlsConfigData.VerifyHost.Flags = EFI_TLS_VERIFY_FLAG_NONE;
+ if (HttpInstance->ProxyConnected) {
+ HttpInstance->TlsConfigData.VerifyHost.HostName = HttpInstance->EndPointRemoteHost;
+ } else {
+ HttpInstance->TlsConfigData.VerifyHost.HostName = HttpInstance->RemoteHost;
+ }

//
// EfiTlsConnectionEnd,
diff --git a/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c b/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c
index 6a5d78629bb3..45087a19350a 100644
--- a/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c
+++ b/NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c
@@ -1927,6 +1927,11 @@ HttpGenRequestMessage (
CopyMem (RequestPtr, HTTP_METHOD_DELETE, StrLength);
RequestPtr += StrLength;
break;
+ case HttpMethodConnect:
+ StrLength = sizeof (HTTP_METHOD_CONNECT) - 1;
+ CopyMem (RequestPtr, HTTP_METHOD_CONNECT, StrLength);
+ RequestPtr += StrLength;
+ break;
default:
ASSERT (FALSE);
Status = EFI_INVALID_PARAMETER;
--
2.36.1.windows.1


Re: [edk2-platforms][PATCH V3 0/4] QemuOpenBoardPkg: Add QemuOpenBoardPkg

Isaac Oram
 

Series pushed as 9a7234827f..f4679715a4

-----Original Message-----
From: Kinney, Michael D <michael.d.kinney@...>
Sent: Tuesday, September 13, 2022 2:51 PM
To: Oram, Isaac W <isaac.w.oram@...>; Theo Jehl <theojehl76@...>; devel@edk2.groups.io; Kinney, Michael D <michael.d.kinney@...>
Cc: Leif Lindholm <quic_llindhol@...>; Pedro Falcato <pedro.falcato@...>; Gerd Hoffmann <kraxel@...>; Stefan Hajnoczi <stefanha@...>
Subject: RE: [edk2-devel][edk2-platforms][PATCH V3 0/4] QemuOpenBoardPkg: Add QemuOpenBoardPkg

Series Acked-by: Michael D Kinney <michael.d.kinney@...>

-----Original Message-----
From: Oram, Isaac W <isaac.w.oram@...>
Sent: Tuesday, September 13, 2022 2:46 PM
To: Theo Jehl <theojehl76@...>; devel@edk2.groups.io
Cc: Leif Lindholm <quic_llindhol@...>; Kinney, Michael D
<michael.d.kinney@...>; Pedro Falcato <pedro.falcato@...>;
Gerd Hoffmann <kraxel@...>; Stefan Hajnoczi
<stefanha@...>
Subject: RE: [edk2-devel][edk2-platforms][PATCH V3 0/4]
QemuOpenBoardPkg: Add QemuOpenBoardPkg

Series Reviewed-by: Isaac Oram <isaac.w.oram@...>

-----Original Message-----
From: Theo Jehl <theojehl76@...>
Sent: Tuesday, September 13, 2022 2:32 PM
To: devel@edk2.groups.io
Cc: Leif Lindholm <quic_llindhol@...>; Kinney, Michael D
<michael.d.kinney@...>; Oram, Isaac W <isaac.w.oram@...>;
Pedro Falcato <pedro.falcato@...>; Gerd Hoffmann
<kraxel@...>; Stefan Hajnoczi <stefanha@...>
Subject: [edk2-devel][edk2-platforms][PATCH V3 0/4] QemuOpenBoardPkg:
Add QemuOpenBoardPkg

QemuOpenBoardPkg adds a MinPlatform port to Qemu x86_64 It can boots
UEFI Linux and Windows, and works on PIIX4 and Q35 This board port provides a simple starting place for investigating edk2 and MinPlatform Arch.
Currently we implement up to stage 4 of the MinPlatform spec and can boot Windows/Linux.

V2 splits the package into several commits.
Each commit corresponding to a MinPlatform architecture stage.

The V3 removes specials characters in "Theo" from file headers.
Cleaned up whitespace, punctuation, commenting to better match coding
style and conventions Fixed Visual Studio build issue converting UINT64 to UINT32.
Fixed build issues related to sync with latest master.

Cc: Leif Lindholm <quic_llindhol@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Isaac Oram <isaac.w.oram@...>
Cc: Pedro Falcato <pedro.falcato@...>
Cc: Gerd Hoffmann <kraxel@...>
Cc: Stefan Hajnoczi <stefanha@...>

Signed-off-by: Theo Jehl <theojehl76@...>

Theo Jehl (4):
QemuOpenBoardPkg: Add QemuOpenBoardPkg
QemuOpenBoardPkg: Enable stage 2
QemuOpenBoardPkg: Enable stage 3
QemuOpenBoardPkg: Enable stage 4

.../QemuOpenBoardPkg/QemuOpenBoardPkg.dec | 33 ++
.../Include/Dsc/Stage1.dsc.inc | 55 +++
.../Include/Dsc/Stage2.dsc.inc | 31 ++
.../Include/Dsc/Stage3.dsc.inc | 101 ++++++
.../Include/Dsc/Stage4.dsc.inc | 56 +++
.../QemuOpenBoardPkg/QemuOpenBoardPkg.dsc | 169 +++++++++
.../QemuOpenBoardPkg/QemuOpenBoardPkg.fdf | 328 ++++++++++++++++++
.../BoardBootManagerLib.inf | 39 +++
.../Library/BoardInitLib/BoardInitLib.inf | 29 ++
.../Library/PeiReportFvLib/PeiReportFvLib.inf | 63 ++++ .../Library/PlatformSecLib/PlatformSecLib.inf | 49 +++
.../QemuOpenFwCfgLib/QemuOpenFwCfgLib.inf | 23 ++
.../PlatformInitPei/PlatformInitPei.inf | 59 ++++
.../Include/Library/QemuOpenFwCfgLib.h | 105 ++++++
.../PlatformInitPei/PlatformInit.h | 59 ++++
.../BoardBootManagerLib/BoardBootManager.c | 105 ++++++
.../Library/BoardInitLib/BoardInitLib.c | 231 ++++++++++++
.../Library/PeiReportFvLib/PeiReportFvLib.c | 285 +++++++++++++++
.../Library/PlatformSecLib/PlatformSecLib.c | 140 ++++++++
.../QemuOpenFwCfgLib/QemuOpenFwCfgLib.c | 136 ++++++++
.../QemuOpenBoardPkg/PlatformInitPei/Cpu.c | 64 ++++
.../QemuOpenBoardPkg/PlatformInitPei/Memory.c | 254 ++++++++++++++
.../QemuOpenBoardPkg/PlatformInitPei/Pci.c | 70 ++++
.../QemuOpenBoardPkg/PlatformInitPei/Pcie.c | 106 ++++++
.../PlatformInitPei/PlatformInit.c | 75 ++++
.../Include/Fdf/FlashMap.fdf.inc | 94 +++++
.../Library/PlatformSecLib/Ia32/SecEntry.nasm | 117 +++++++
Platform/Qemu/QemuOpenBoardPkg/README.md | 53 +++
28 files changed, 2929 insertions(+)
create mode 100644
Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.dec
create mode 100644
Platform/Qemu/QemuOpenBoardPkg/Include/Dsc/Stage1.dsc.inc
create mode 100644
Platform/Qemu/QemuOpenBoardPkg/Include/Dsc/Stage2.dsc.inc
create mode 100644
Platform/Qemu/QemuOpenBoardPkg/Include/Dsc/Stage3.dsc.inc
create mode 100644
Platform/Qemu/QemuOpenBoardPkg/Include/Dsc/Stage4.dsc.inc
create mode 100644
Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.dsc
create mode 100644
Platform/Qemu/QemuOpenBoardPkg/QemuOpenBoardPkg.fdf
create mode 100644
Platform/Qemu/QemuOpenBoardPkg/Library/BoardBootManagerLib/BoardBootMa
nagerLib.inf create mode 100644
Platform/Qemu/QemuOpenBoardPkg/Library/BoardInitLib/BoardInitLib.inf
create mode 100644
Platform/Qemu/QemuOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.i
nf create mode 100644
Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/PlatformSecLib.i
nf create mode 100644
Platform/Qemu/QemuOpenBoardPkg/Library/QemuOpenFwCfgLib/QemuOpenFwCfgL
ib.inf create mode 100644
Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInitPei.inf
create mode 100644
Platform/Qemu/QemuOpenBoardPkg/Include/Library/QemuOpenFwCfgLib.h
create mode 100644
Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInit.h
create mode 100644
Platform/Qemu/QemuOpenBoardPkg/Library/BoardBootManagerLib/BoardBootMa
nager.c create mode 100644
Platform/Qemu/QemuOpenBoardPkg/Library/BoardInitLib/BoardInitLib.c
create mode 100644
Platform/Qemu/QemuOpenBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c
create mode 100644
Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/PlatformSecLib.c
create mode 100644
Platform/Qemu/QemuOpenBoardPkg/Library/QemuOpenFwCfgLib/QemuOpenFwCfgL
ib.c create mode 100644
Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Cpu.c
create mode 100644
Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Memory.c
create mode 100644
Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Pci.c
create mode 100644
Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/Pcie.c
create mode 100644
Platform/Qemu/QemuOpenBoardPkg/PlatformInitPei/PlatformInit.c
create mode 100644
Platform/Qemu/QemuOpenBoardPkg/Include/Fdf/FlashMap.fdf.inc
create mode 100644
Platform/Qemu/QemuOpenBoardPkg/Library/PlatformSecLib/Ia32/SecEntry.na
sm create mode 100644 Platform/Qemu/QemuOpenBoardPkg/README.md

--
2.37.0 (Apple Git-136)


[PATCH] NetworkPkg: Add WiFi profile sync protocol support

Clark-williams, Zachary
 

From: Zachary Clark-Williams <zclarkw112@...>

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

Enables KVM and One Click Recovery WLAN capability with WiFi Profile
Sync feature and protocol. Adding WiFiProfileSyncProtocol, which
supports the profilesync driver operations for transferring WiFi profiles
from AMT to the Supplicant. WiFiConnectionManager will check for the
WifiProfileSyncProtocol and if found will operate on the premise of a
One Click Recovery, or KVM flow with a Wifi profile provided by AMT.

Signed-off-by: Zachary Clark-Williams <zachary.clark-williams@...>
---
.../Protocol/WiFiProfileSyncProtocol.h | 83 ++++++++
NetworkPkg/NetworkPkg.dec | 3 +
.../WifiConnectionManagerDxe.inf | 3 +-
.../WifiConnectionMgrDriver.c | 126 +++++++----
.../WifiConnectionMgrDxe.h | 4 +-
.../WifiConnectionMgrImpl.c | 197 ++++++++++++++++--
.../WifiConnectionMgrMisc.c | 13 ++
7 files changed, 370 insertions(+), 59 deletions(-)
create mode 100644 NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h

diff --git a/NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h b/NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h
new file mode 100644
index 0000000000..e36daceabf
--- /dev/null
+++ b/NetworkPkg/Include/Protocol/WiFiProfileSyncProtocol.h
@@ -0,0 +1,83 @@
+/** @file
+ WiFi profile sync protocol. Supports One Click Recovery or KVM OS recovery
+ boot flow over WiFi.
+
+ Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef WIFI_PROFILE_SYNC_PROTOCOL_H_
+#define WIFI_PROFILE_SYNC_PROTOCOL_H_
+
+#include <WifiConnectionManagerDxe/WifiConnectionMgrConfig.h>
+
+//
+// WiFi Profile Sync Protocol GUID variable.
+//
+extern EFI_GUID gEfiWiFiProfileSyncProtocolGuid;
+
+/**
+ Used by the WiFi connection manager to get the WiFi profile that AMT shared
+ and was stored in WiFi profile protocol. Aligns the AMT WiFi profile data to
+ the WiFi connection manager profile structure fo connection use.
+
+ @param[in, out] WcmProfile WiFi Connection Manager profile structure
+ @param[in, out] MacAddress MAC address from AMT saved to NiC MAC address
+
+ @retval EFI_SUCCESS Stored WiFi profile converted and returned succefully
+ @retval EFI_UNSUPPORTED Profile protocol sharing not supported or enabled
+ @retval EFI_NOT_FOUND No profiles to returned
+ @retval Others Error Occurred
+**/
+typedef
+EFI_STATUS
+(EFIAPI *WIFI_PROFILE_GET)(
+ IN OUT WIFI_MGR_NETWORK_PROFILE *Profile,
+ IN OUT EFI_80211_MAC_ADDRESS MacAddress
+ );
+
+/**
+ Saves the WiFi connection status recieved by the WiFiConnectionManager when
+ in a KVM OR One Click Recovery WLAN recovery flow. Input as
+ EFI_80211_CONNECT_NETWORK_RESULT_CODE then converted and stored as EFI_STATUS type.
+
+ @param[in] ConnectionStatus WiFi connection attempt results
+**/
+typedef
+VOID
+(EFIAPI *WIFI_SET_CONNECT_STATE)(
+ IN EFI_80211_CONNECT_NETWORK_RESULT_CODE ConnectionStatus
+ );
+
+/**
+ Retrieves the stored WiFi connection status when in either KVM OR One Click
+ Recovery WLAN recovery flow.
+
+ @retval EFI_SUCCESS WiFi connection completed succesfully
+ @retval Others Connection failure occurred
+**/
+typedef
+EFI_STATUS
+(EFIAPI *WIFI_GET_CONNECT_STATE)(
+ VOID
+ );
+
+//
+// WiFi Profile Sync Protocol structure.
+//
+typedef struct {
+ UINT32 Revision;
+ WIFI_SET_CONNECT_STATE WifiProfileSyncSetConnectState;
+ WIFI_GET_CONNECT_STATE WifiProfileSyncGetConnectState;
+ WIFI_PROFILE_GET WifiProfileSyncGetProfile;
+} EFI_WIFI_PROFILE_SYNC_PROTOCOL;
+
+/**
+ WiFi Profile Protocol revision number.
+
+ Revision 1: Initial version
+**/
+#define EFI_WIFI_PROFILE_SYNC_PROTOCOL_REVISION 1
+
+#endif // WIFI_PROFILE_SYNC_PROTOCOL_H_
diff --git a/NetworkPkg/NetworkPkg.dec b/NetworkPkg/NetworkPkg.dec
index 5e43ebf8c5..53fb34c4a0 100644
--- a/NetworkPkg/NetworkPkg.dec
+++ b/NetworkPkg/NetworkPkg.dec
@@ -91,6 +91,9 @@
## Include/Protocol/HttpCallback.h
gEdkiiHttpCallbackProtocolGuid = {0x611114f1, 0xa37b, 0x4468, {0xa4, 0x36, 0x5b, 0xdd, 0xa1, 0x6a, 0xa2, 0x40}}

+ ## Include/Protocol/WiFiProfileSyncProtocol.h
+ gEfiWiFiProfileSyncProtocolGuid = {0x399a2b8a, 0xc267, 0x44aa, {0x9a, 0xb4, 0x30, 0x58, 0x8c, 0xd2, 0x2d, 0xcc}}
+
[PcdsFixedAtBuild]
## The max attempt number will be created by iSCSI driver.
# @Prompt Max attempt number.
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf
index 4394b6f4bb..7e36016cf8 100644
--- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf
+++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf
@@ -9,7 +9,7 @@
# 2). WPA2 Personal Network
# 3). EAP Networks (EAP-TLS, EAP-TTLS/MSCHAPv2 and PEAPv0/MSCHAPv2)
#
-# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2019 - 2022, Intel Corporation. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -71,6 +71,7 @@
gEfiAdapterInformationProtocolGuid ## SOMETIMES_CONSUMES
gEfiSupplicantProtocolGuid ## SOMETIMES_CONSUMES
gEfiEapConfigurationProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiWiFiProfileSyncProtocolGuid ## SOMETIMES_CONSUMES

[Guids]
gWifiConfigGuid ## PRODUCES ## GUID
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c
index 67a01ca058..65df5b2c8a 100644
--- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c
+++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c
@@ -1,7 +1,7 @@
/** @file
The driver binding protocol for the WiFi Connection Manager.

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

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

@@ -39,6 +39,11 @@ EFI_GUID mWifiConfigNetworkListRefreshGuid = WIFI_CONFIG_NETWORK_LIST_REFRESH_G
EFI_GUID mWifiConfigConnectFormRefreshGuid = WIFI_CONFIG_CONNECT_FORM_REFRESH_GUID;
EFI_GUID mWifiConfigMainFormRefreshGuid = WIFI_CONFIG_MAIN_FORM_REFRESH_GUID;

+//
+// Wifi connection attempt counter for retries
+//
+extern UINT8 WifiConnectionCount;
+
/**
Tests to see if this driver supports a given controller. If a child device is provided,
it further tests to see if this driver supports creating a handle for the specified child device.
@@ -167,8 +172,10 @@ WifiMgrDxeDriverBindingStart (
EFI_WIRELESS_MAC_CONNECTION_II_PROTOCOL *Wmp;
EFI_SUPPLICANT_PROTOCOL *Supplicant;
EFI_EAP_CONFIGURATION_PROTOCOL *EapConfig;
+ EFI_WIFI_PROFILE_SYNC_PROTOCOL *WiFiProfileSyncProtocol;

- Nic = NULL;
+ WifiConnectionCount = 0;
+ Nic = NULL;

//
// Open Protocols
@@ -236,47 +243,73 @@ WifiMgrDxeDriverBindingStart (
InitializeListHead (&Nic->ProfileList);

//
- // Record the MAC address of the incoming NIC.
+ // WiFi profile sync protocol installation check for OS recovery flow.
//
- Status = NetLibGetMacAddress (
- ControllerHandle,
- (EFI_MAC_ADDRESS *)&Nic->MacAddress,
- &AddressSize
- );
- if (EFI_ERROR (Status)) {
- goto ERROR2;
- }
-
- //
- // Create and start the timer for the status check
- //
- Status = gBS->CreateEvent (
- EVT_NOTIFY_SIGNAL | EVT_TIMER,
- TPL_CALLBACK,
- WifiMgrOnTimerTick,
- Nic,
- &Nic->TickTimer
+ Status = gBS->LocateProtocol (
+ &gEfiWiFiProfileSyncProtocolGuid,
+ NULL,
+ (VOID **)&WiFiProfileSyncProtocol
);
- if (EFI_ERROR (Status)) {
- goto ERROR2;
- }
+ if (!EFI_ERROR (Status)) {
+ Nic->ConnectPendingNetwork = (WIFI_MGR_NETWORK_PROFILE *)AllocateZeroPool (sizeof (WIFI_MGR_NETWORK_PROFILE));
+ if (Nic->ConnectPendingNetwork == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ERROR1;
+ }

- Status = gBS->SetTimer (Nic->TickTimer, TimerPeriodic, EFI_TIMER_PERIOD_MILLISECONDS (500));
- if (EFI_ERROR (Status)) {
- goto ERROR3;
- }
+ WiFiProfileSyncProtocol->WifiProfileSyncGetProfile (Nic->ConnectPendingNetwork, Nic->MacAddress);
+ if (Nic->ConnectPendingNetwork != NULL) {
+ Status = WifiMgrConnectToNetwork (Nic, Nic->ConnectPendingNetwork);
+ if (EFI_ERROR (Status)) {
+ WiFiProfileSyncProtocol->WifiProfileSyncSetConnectState (Status);
+ }
+ } else {
+ goto ERROR1;
+ }
+ } else {
+ //
+ // Record the MAC address of the incoming NIC.
+ //
+ Status = NetLibGetMacAddress (
+ ControllerHandle,
+ (EFI_MAC_ADDRESS *)&Nic->MacAddress,
+ &AddressSize
+ );
+ if (EFI_ERROR (Status)) {
+ goto ERROR2;
+ }

- Nic->ConnectState = WifiMgrDisconnected;
- Nic->ScanState = WifiMgrScanFinished;
+ //
+ // Create and start the timer for the status check
+ //
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL | EVT_TIMER,
+ TPL_CALLBACK,
+ WifiMgrOnTimerTick,
+ Nic,
+ &Nic->TickTimer
+ );
+ if (EFI_ERROR (Status)) {
+ goto ERROR2;
+ }

- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
- InsertTailList (&mPrivate->NicList, &Nic->Link);
- Nic->NicIndex = mPrivate->NicCount++;
- if (mPrivate->CurrentNic == NULL) {
- mPrivate->CurrentNic = Nic;
- }
+ Status = gBS->SetTimer (Nic->TickTimer, TimerPeriodic, EFI_TIMER_PERIOD_MILLISECONDS (500));
+ if (EFI_ERROR (Status)) {
+ goto ERROR3;
+ }

- gBS->RestoreTPL (OldTpl);
+ Nic->ConnectState = WifiMgrDisconnected;
+ Nic->ScanState = WifiMgrScanFinished;
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+ InsertTailList (&mPrivate->NicList, &Nic->Link);
+ Nic->NicIndex = mPrivate->NicCount++;
+ if (mPrivate->CurrentNic == NULL) {
+ mPrivate->CurrentNic = Nic;
+ }
+
+ gBS->RestoreTPL (OldTpl);
+ }

Status = gBS->InstallProtocolInterface (
&ControllerHandle,
@@ -385,10 +418,11 @@ WifiMgrDxeDriverBindingStop (
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
)
{
- EFI_STATUS Status;
- EFI_TPL OldTpl;
- WIFI_MGR_PRIVATE_PROTOCOL *WifiMgrIdentifier;
- WIFI_MGR_DEVICE_DATA *Nic;
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+ WIFI_MGR_PRIVATE_PROTOCOL *WifiMgrIdentifier;
+ WIFI_MGR_DEVICE_DATA *Nic;
+ EFI_WIFI_PROFILE_SYNC_PROTOCOL *WiFiProfileSyncProtocol;

Status = gBS->OpenProtocol (
ControllerHandle,
@@ -481,7 +515,15 @@ WifiMgrDxeDriverBindingStop (
//
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

- RemoveEntryList (&Nic->Link);
+ Status = gBS->LocateProtocol (
+ &gEfiWiFiProfileSyncProtocolGuid,
+ NULL,
+ (VOID **)&WiFiProfileSyncProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ RemoveEntryList (&Nic->Link);
+ }
+
mPrivate->NicCount--;
if (mPrivate->CurrentNic == Nic) {
mPrivate->CurrentNic = NULL;
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h
index 7b2e41e155..047f85dbc2 100644
--- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h
+++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h
@@ -47,6 +47,7 @@
#include <Protocol/SimpleNetwork.h>
#include <Protocol/SimpleFileSystem.h>
#include <Protocol/EapConfiguration.h>
+#include <Protocol/WiFiProfileSyncProtocol.h>

//
// Produced Protocols
@@ -73,7 +74,8 @@
//
#define WIFI_MGR_DXE_VERSION 0xb

-#define OUI_IEEE_80211I 0xAC0F00
+#define OUI_IEEE_80211I 0xAC0F00
+#define MAX_WIFI_CONNETION_ATTEMPTS 3

typedef enum {
Ieee80211PairwiseCipherSuiteUseGroupCipherSuite = 0,
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c
index 59bac48c42..3a04b4ddb1 100644
--- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c
+++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c
@@ -19,6 +19,8 @@ EFI_EAP_TYPE mEapSecondAuthMethod[] = {
EFI_EAP_TYPE_MSCHAPV2
};

+UINT8 WifiConnectionCount = 0;
+
/**
The callback function for scan operation. This function updates networks
according to the latest scan result, and trigger UI refresh.
@@ -420,22 +422,34 @@ WifiMgrConfigPassword (
//
// Set password to supplicant
//
+ if (Profile->Password[StrLen (Profile->Password)] != '\0') {
+ Profile->Password[StrLen (Profile->Password)] = L'\0';
+ }
+
if (StrLen (Profile->Password) < PASSWORD_MIN_LEN) {
return EFI_NOT_FOUND;
}

- AsciiPassword = AllocateZeroPool ((StrLen (Profile->Password) + 1) * sizeof (UINT8));
+ if (StrLen (Profile->Password) > PASSWORD_STORAGE_SIZE) {
+ ASSERT (EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ AsciiPassword = AllocateZeroPool ((StrLen (Profile->Password) + 1) * sizeof (CHAR8));
if (AsciiPassword == NULL) {
return EFI_OUT_OF_RESOURCES;
}

- UnicodeStrToAsciiStrS (Profile->Password, (CHAR8 *)AsciiPassword, PASSWORD_STORAGE_SIZE);
- Status = Supplicant->SetData (
- Supplicant,
- EfiSupplicant80211PskPassword,
- AsciiPassword,
- (StrLen (Profile->Password) + 1) * sizeof (UINT8)
- );
+ Status = UnicodeStrToAsciiStrS (Profile->Password, (CHAR8 *)AsciiPassword, ((StrLen (Profile->Password) + 1) * sizeof (CHAR8)));
+ if (!EFI_ERROR (Status)) {
+ Status = Supplicant->SetData (
+ Supplicant,
+ EfiSupplicant80211PskPassword,
+ AsciiPassword,
+ (StrLen (Profile->Password) + 1) * sizeof (CHAR8)
+ );
+ }
+
ZeroMem (AsciiPassword, AsciiStrLen ((CHAR8 *)AsciiPassword) + 1);
FreePool (AsciiPassword);

@@ -466,6 +480,7 @@ WifiMgrConfigEap (
)
{
EFI_STATUS Status;
+ EFI_WIFI_PROFILE_SYNC_PROTOCOL *WiFiProfileSyncProtocol;
EFI_EAP_CONFIGURATION_PROTOCOL *EapConfig;
EFI_EAP_TYPE EapAuthMethod;
EFI_EAP_TYPE EapSecondAuthMethod;
@@ -567,7 +582,13 @@ WifiMgrConfigEap (
return EFI_OUT_OF_RESOURCES;
}

- UnicodeStrToAsciiStrS (Profile->EapIdentity, Identity, IdentitySize);
+ Status = gBS->LocateProtocol (&gEfiWiFiProfileSyncProtocolGuid, NULL, (VOID **)&WiFiProfileSyncProtocol);
+ if (!EFI_ERROR (Status)) {
+ CopyMem (Identity, &Profile->EapIdentity, IdentitySize);
+ } else {
+ UnicodeStrToAsciiStrS (Profile->EapIdentity, Identity, IdentitySize);
+ }
+
Status = EapConfig->SetData (
EapConfig,
EFI_EAP_TYPE_IDENTITY,
@@ -892,6 +913,133 @@ WifiMgrPrepareConnection (
return EFI_SUCCESS;
}

+/**
+ Will reset NiC data, get profile from profile sync driver, and send for
+ another connection attempt.This function should not be called more than
+ 3 times.
+
+ @param[in] WiFiProfileSyncProtocol The target network profile to connect.
+
+ @retval EFI_SUCCESS The operation is completed.
+ @retval other Operation failure.
+
+**/
+EFI_STATUS
+ConnectionRetry (
+ IN EFI_WIFI_PROFILE_SYNC_PROTOCOL *WiFiProfileSyncProtocol
+ )
+{
+ EFI_STATUS Status;
+ WIFI_MGR_DEVICE_DATA *Nic;
+ EFI_WIRELESS_MAC_CONNECTION_II_PROTOCOL *Wmp;
+ EFI_SUPPLICANT_PROTOCOL *Supplicant;
+ EFI_EAP_CONFIGURATION_PROTOCOL *EapConfig;
+
+ Nic = NULL;
+
+ Status = gBS->LocateProtocol (
+ &gEfiWiFi2ProtocolGuid,
+ NULL,
+ (VOID **)&Wmp
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gBS->LocateProtocol (
+ &gEfiSupplicantProtocolGuid,
+ NULL,
+ (VOID **)&Supplicant
+ );
+ if (EFI_ERROR (Status)) {
+ Supplicant = NULL;
+ }
+
+ Status = gBS->LocateProtocol (
+ &gEfiEapConfigurationProtocolGuid,
+ NULL,
+ (VOID **)&EapConfig
+ );
+ if (EFI_ERROR (Status)) {
+ EapConfig = NULL;
+ }
+
+ //
+ // Initialize Nic device data
+ //
+ Nic = AllocateZeroPool (sizeof (WIFI_MGR_DEVICE_DATA));
+ if (Nic == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Nic->Signature = WIFI_MGR_DEVICE_DATA_SIGNATURE;
+ Nic->Private = mPrivate;
+ Nic->Wmp = Wmp;
+ Nic->Supplicant = Supplicant;
+ Nic->EapConfig = EapConfig;
+ Nic->UserSelectedProfile = NULL;
+ Nic->OneTimeScanRequest = FALSE;
+
+ if (Nic->Supplicant != NULL) {
+ Status = WifiMgrGetSupportedSuites (Nic);
+ }
+
+ if (!EFI_ERROR (Status)) {
+ InitializeListHead (&Nic->ProfileList);
+
+ Nic->ConnectPendingNetwork = (WIFI_MGR_NETWORK_PROFILE *)AllocateZeroPool (sizeof (WIFI_MGR_NETWORK_PROFILE));
+ if (Nic->ConnectPendingNetwork == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to allocate memory for ConnectPendingNetwork\n"));
+ goto ERROR;
+ }
+
+ Status = WiFiProfileSyncProtocol->WifiProfileSyncGetProfile (Nic->ConnectPendingNetwork, Nic->MacAddress);
+ if (!EFI_ERROR (Status) && (Nic->ConnectPendingNetwork != NULL)) {
+ Status = WifiMgrConnectToNetwork (Nic, Nic->ConnectPendingNetwork);
+ if (!EFI_ERROR (Status)) {
+ return Status;
+ }
+ } else {
+ DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to get WiFi profile with status %r\n", Status));
+ }
+ } else {
+ DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Failed to get Supported suites with status %r\n", Status));
+ }
+
+ if (Nic->ConnectPendingNetwork != NULL) {
+ if (Nic->ConnectPendingNetwork->Network.AKMSuite != NULL) {
+ FreePool (Nic->ConnectPendingNetwork->Network.AKMSuite);
+ }
+
+ if (Nic->ConnectPendingNetwork->Network.CipherSuite != NULL) {
+ FreePool (Nic->ConnectPendingNetwork->Network.CipherSuite);
+ }
+
+ FreePool (Nic->ConnectPendingNetwork);
+ }
+
+ERROR:
+ if (Nic->Supplicant != NULL) {
+ if (Nic->SupportedSuites.SupportedAKMSuites != NULL) {
+ FreePool (Nic->SupportedSuites.SupportedAKMSuites);
+ }
+
+ if (Nic->SupportedSuites.SupportedSwCipherSuites != NULL) {
+ FreePool (Nic->SupportedSuites.SupportedSwCipherSuites);
+ }
+
+ if (Nic->SupportedSuites.SupportedHwCipherSuites != NULL) {
+ FreePool (Nic->SupportedSuites.SupportedHwCipherSuites);
+ }
+ }
+
+ FreePool (Nic);
+
+ return Status;
+}
+
/**
The callback function for connect operation.

@@ -908,12 +1056,13 @@ WifiMgrOnConnectFinished (
IN VOID *Context
)
{
- EFI_STATUS Status;
- WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken;
- WIFI_MGR_NETWORK_PROFILE *ConnectedProfile;
- UINT8 SecurityType;
- UINT8 SSIdLen;
- CHAR8 *AsciiSSId;
+ EFI_STATUS Status;
+ WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken;
+ WIFI_MGR_NETWORK_PROFILE *ConnectedProfile;
+ UINT8 SecurityType;
+ UINT8 SSIdLen;
+ CHAR8 *AsciiSSId;
+ EFI_WIFI_PROFILE_SYNC_PROTOCOL *WiFiProfileSyncProtocol;

ASSERT (Context != NULL);

@@ -925,6 +1074,24 @@ WifiMgrOnConnectFinished (
ASSERT (ConfigToken->Type == TokenTypeConnectNetworkToken);

ASSERT (ConfigToken->Token.ConnectNetworkToken != NULL);
+
+ Status = gBS->LocateProtocol (&gEfiWiFiProfileSyncProtocolGuid, NULL, (VOID **)&WiFiProfileSyncProtocol);
+ if (!EFI_ERROR (Status)) {
+ WiFiProfileSyncProtocol->WifiProfileSyncSetConnectState (ConfigToken->Token.ConnectNetworkToken->ResultCode);
+ if ((WifiConnectionCount < MAX_WIFI_CONNETION_ATTEMPTS) &&
+ (ConfigToken->Token.ConnectNetworkToken->ResultCode != ConnectSuccess))
+ {
+ WifiConnectionCount++;
+ gBS->CloseEvent (Event);
+ Status = ConnectionRetry (WiFiProfileSyncProtocol);
+ if (!EFI_ERROR (Status)) {
+ return;
+ }
+
+ WiFiProfileSyncProtocol->WifiProfileSyncSetConnectState (Status);
+ }
+ }
+
if (ConfigToken->Token.ConnectNetworkToken->Status != EFI_SUCCESS) {
if (ConfigToken->Nic->OneTimeConnectRequest) {
//
diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c
index 4ad5643c24..87adfc5033 100644
--- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c
+++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c
@@ -672,10 +672,23 @@ WifiMgrCleanProfileSecrets (
IN WIFI_MGR_NETWORK_PROFILE *Profile
)
{
+ EFI_STATUS Status;
+ EFI_WIFI_PROFILE_SYNC_PROTOCOL *WiFiProfileSyncProtocol;
+
ZeroMem (Profile->Password, sizeof (CHAR16) * PASSWORD_STORAGE_SIZE);
ZeroMem (Profile->EapPassword, sizeof (CHAR16) * PASSWORD_STORAGE_SIZE);
ZeroMem (Profile->PrivateKeyPassword, sizeof (CHAR16) * PASSWORD_STORAGE_SIZE);

+ //
+ // When EFI WiFi profile sync protocol is found the system is performing a recovery boot in secure
+ // boot mode. The profile sync driver will manage the CA certificate, client certificate, and key
+ // data, cleaning them at exit boot services.
+ //
+ Status = gBS->LocateProtocol (&gEfiWiFiProfileSyncProtocolGuid, NULL, (VOID **)&WiFiProfileSyncProtocol);
+ if (!EFI_ERROR (Status)) {
+ return;
+ }
+
if (Profile->CACertData != NULL) {
ZeroMem (Profile->CACertData, Profile->CACertSize);
FreePool (Profile->CACertData);
--
2.26.2.windows.1


[edk2-platforms][PATCH V1 2/2] MinPlatformPkg/S3: Use EFI_PHYSICAL_ADDRESS for address

Isaac Oram
 

This change fixes build warnings with type casts from some compilers.
Also changes type for ACPI_S3_MEMORY S3PeiMemBase to EFI_PHYSICAL_ADDRESS.
This generally makes code eaiser to understand as opposed to UINT64.

Cc: Sai Chaganty <rangasai.v.chaganty@...>
Cc: Nate DeSimone <nathaniel.l.desimone@...>
Cc: Liming Gao <gaoliming@...>
Cc: Chasel Chiu <chasel.chiu@...>
Cc: Eric Dong <eric.dong@...>
Cc: Benjamin Doron <benjamin.doron00@...>
Signed-off-by: Isaac Oram <isaac.w.oram@...>
---
.../Intel/PowerManagement/S3FeaturePkg/S3Dxe/S3Dxe.c | 10 +++++-----
.../Intel/PowerManagement/S3FeaturePkg/S3Pei/S3Pei.c | 2 +-
.../Intel/MinPlatformPkg/Include/AcpiS3MemoryNvData.h | 4 ++--
3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/Features/Intel/PowerManagement/S3FeaturePkg/S3Dxe/S3Dxe.c b/Features/Intel/PowerManagement/S3FeaturePkg/S3Dxe/S3Dxe.c
index 1a7ccb8eed..47b2cc27a5 100644
--- a/Features/Intel/PowerManagement/S3FeaturePkg/S3Dxe/S3Dxe.c
+++ b/Features/Intel/PowerManagement/S3FeaturePkg/S3Dxe/S3Dxe.c
@@ -124,19 +124,19 @@ S3DxeEntryPoint (
IN EFI_SYSTEM_TABLE *SystemTable
)
{
- UINT64 S3PeiMemSize;
- UINT64 S3PeiMemBase;
+ UINTN S3PeiMemSize;
+ UINTN S3PeiMemBase;
ACPI_S3_MEMORY S3MemoryInfo;
EFI_STATUS Status;

DEBUG ((DEBUG_INFO, "%a() Start\n", __FUNCTION__));

- S3PeiMemSize = GetPeiMemSize ();
+ S3PeiMemSize = (UINTN) GetPeiMemSize ();
S3PeiMemBase = (UINTN) AllocateAcpiNvsMemoryBelow4G (S3PeiMemSize);
ASSERT (S3PeiMemBase != 0);

- S3MemoryInfo.S3PeiMemBase = S3PeiMemBase;
- S3MemoryInfo.S3PeiMemSize = S3PeiMemSize;
+ S3MemoryInfo.S3PeiMemBase = (EFI_PHYSICAL_ADDRESS) S3PeiMemBase;
+ S3MemoryInfo.S3PeiMemSize = (UINT64) S3PeiMemSize;

DEBUG ((DEBUG_INFO, "S3PeiMemBase: 0x%x\n", S3PeiMemBase));
DEBUG ((DEBUG_INFO, "S3PeiMemSize: 0x%x\n", S3PeiMemSize));
diff --git a/Features/Intel/PowerManagement/S3FeaturePkg/S3Pei/S3Pei.c b/Features/Intel/PowerManagement/S3FeaturePkg/S3Pei/S3Pei.c
index 6acb894b6f..388e0954bd 100644
--- a/Features/Intel/PowerManagement/S3FeaturePkg/S3Pei/S3Pei.c
+++ b/Features/Intel/PowerManagement/S3FeaturePkg/S3Pei/S3Pei.c
@@ -40,7 +40,7 @@ FspSiliconInitDoneNotify (
{
EFI_STATUS Status;
EFI_BOOT_MODE BootMode;
- UINT64 MchBaseAddress;
+ UINTN MchBaseAddress;

Status = PeiServicesGetBootMode (&BootMode);
ASSERT_EFI_ERROR (Status);
diff --git a/Platform/Intel/MinPlatformPkg/Include/AcpiS3MemoryNvData.h b/Platform/Intel/MinPlatformPkg/Include/AcpiS3MemoryNvData.h
index 04eb1435ee..35943e2aa3 100644
--- a/Platform/Intel/MinPlatformPkg/Include/AcpiS3MemoryNvData.h
+++ b/Platform/Intel/MinPlatformPkg/Include/AcpiS3MemoryNvData.h
@@ -13,8 +13,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
// NV data structure
//
typedef struct {
- UINT64 S3PeiMemBase;
- UINT64 S3PeiMemSize;
+ EFI_PHYSICAL_ADDRESS S3PeiMemBase;
+ UINT64 S3PeiMemSize;
} ACPI_S3_MEMORY;

#define ACPI_S3_MEMORY_NV_NAME L"S3MemoryInfo"
--
2.36.1.windows.1


[edk2-platforms][PATCH V1 1/2] S3FeaturePkg/Build: Add libraries needed by S3FeaturePkg

Isaac Oram
 

This change is needed for proposed S3FeaturePkg additions.
Changes ensure standalone build for S3FeaturePkg and AdvancedFeaturePkg

Cc: Sai Chaganty <rangasai.v.chaganty@...>
Cc: Nate DeSimone <nathaniel.l.desimone@...>
Cc: Liming Gao <gaoliming@...>
Cc: Benjamin Doron <benjamin.doron00@...>
Signed-off-by: Isaac Oram <isaac.w.oram@...>
---
Features/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dsc | 3 +++
Features/Intel/PowerManagement/S3FeaturePkg/S3FeaturePkg.dsc | 3 +++
2 files changed, 6 insertions(+)

diff --git a/Features/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dsc b/Features/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dsc
index ce0eac7a56..18929589c5 100644
--- a/Features/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dsc
+++ b/Features/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dsc
@@ -115,6 +115,9 @@
[LibraryClasses.Common]
PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf # Required by BeepDebugFeature

+[LibraryClasses.Common.PEIM]
+ SmmAccessLib|IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAccessLib/PeiSmmAccessLib.inf # Required by S3Feature
+
#
# This package builds all advanced features.
#
diff --git a/Features/Intel/PowerManagement/S3FeaturePkg/S3FeaturePkg.dsc b/Features/Intel/PowerManagement/S3FeaturePkg/S3FeaturePkg.dsc
index cd4b1c4f19..d5efcf6b6d 100644
--- a/Features/Intel/PowerManagement/S3FeaturePkg/S3FeaturePkg.dsc
+++ b/Features/Intel/PowerManagement/S3FeaturePkg/S3FeaturePkg.dsc
@@ -41,6 +41,9 @@
!include MinPlatformPkg/Include/Dsc/CorePeiLib.dsc
!include MinPlatformPkg/Include/Dsc/CoreDxeLib.dsc

+[LibraryClasses]
+ PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf
+
[LibraryClasses.common.PEIM]
SmmAccessLib|IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAccessLib/PeiSmmAccessLib.inf

--
2.36.1.windows.1


[edk2-platforms][PATCH V1 0/2] Platforms/Intel: Build fixes

Isaac Oram
 

The S3FeaturePkg changes in
[edk2-platforms][PATCH v3 2/4] S3FeaturePkg: Implement working S3 resume

Introduces some build issues with standalone package build for S3FeaturePkg and
AdvancedFeaturePkg. There are also some type cast related compiler warnings.

We do not currently have continuous integration testing.
We do not currently have documented build testing configuration requirements.
Therefore I am just fixing the minor issues and intend to merge both patch
series together to maintain git bisect to the best of my ability.
I do plan to document required and recommended board port and feature pkg
builds.

Note that the use of UINTN for intermediate data instead of
EFI_PHYSICAL_ADDRESS is only to be consistent with other ACPI implementations
of similar functionality.

Cc: Sai Chaganty <rangasai.v.chaganty@...>
Cc: Nate DeSimone <nathaniel.l.desimone@...>
Cc: Liming Gao <gaoliming@...>
Cc: Chasel Chiu <chasel.chiu@...>
Cc: Eric Dong <eric.dong@...>
Cc: Benjamin Doron <benjamin.doron00@...>
Signed-off-by: Isaac Oram <isaac.w.oram@...>

Isaac Oram (2):
S3FeaturePkg/Build: Add libraries needed by S3FeaturePkg
MinPlatformPkg/S3: Use EFI_PHYSICAL_ADDRESS for address

.../Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dsc | 3 +++
.../Intel/PowerManagement/S3FeaturePkg/S3Dxe/S3Dxe.c | 10 +++++-----
.../PowerManagement/S3FeaturePkg/S3FeaturePkg.dsc | 3 +++
.../Intel/PowerManagement/S3FeaturePkg/S3Pei/S3Pei.c | 2 +-
.../Intel/MinPlatformPkg/Include/AcpiS3MemoryNvData.h | 4 ++--
5 files changed, 14 insertions(+), 8 deletions(-)

--
2.36.1.windows.1


Re: [PATCH v2] UnitTestFrameworkPkg: Add code coverage support for GCC

Michael D Kinney
 

So if you run the stuart command with that plugin available on Linux/GCC, then both the  .gcda and HTML content is always generated and local user can either view HTML content with browser or view the results in VS Code with the .gcda files.  Correct?

 

I think there ways to run the stuart command for just that single pluigin specified on the command line, so the builds are as fast as possible during unit test development.  Would be good to capture that in the ReadMe.md as well.

 

Thanks,

 

Mike

 

From: Guo, Gua <gua.guo@...>
Sent: Tuesday, September 13, 2022 7:11 PM
To: Kinney, Michael D <michael.d.kinney@...>; Sean Brogan <spbrogan@...>; devel@edk2.groups.io
Cc: Sean Brogan <sean.brogan@...>; Michael Kubacki <mikuback@...>
Subject: RE: [edk2-devel] [PATCH v2] UnitTestFrameworkPkg: Add code coverage support for GCC

 

@Sean Brogan

 

I go through the code Merged PR 5008: Initial implementation or code coverage on basecore u… · microsoft/mu_basecore@f6af51f (github.com)

It looks good from my view point.

 

@Kinney, Michael D

Does that pytool plugin support viewing the code coverage visually in C source files? Yes

Either HTML or preferably an Visual Studio Code plugin? I think it can be supported by both based on below change. Due to VScode plugin is auto scan *.gcda and show the result in VScode source tree.
Merged PR 5008: Initial implementation or code coverage on basecore u… · microsoft/mu_basecore@f6af51f (github.com)

 

Flow for stuart_ci_build: (a) -> (b) -> (c) -> (d) -> (e) -> (f)

Flow for vscode extension Gcov Viewer - Visual Studio Marketplace:  (a) -> (b) -> (c) -> (d) -> (g)


(a) stuart_ci_build -p XXXPkg

(b) Call Edk2/.pytool/Plugin/HostUnitTestCompilerPlugin/HostUnitTestCompilerPlugin.py

(c) Call Edk2/BaseTools/Plugin/HostBasedUnitTestRunner/HostBasedUnitTestRunner.py

(d)       execute Build/XXXPkg/**/*Test* -> generate *.gcda files

(e)       use “lcov” tool to parse *.gcda

(f)        use “pycobertura” tool to generate index.html

(g) vscode extension to parse *.gcda and show it on source code directly.


Can it be updated to support VS compilers tool? No, currently I don’t find a good way to generate code coverage for MSVC compiler

 

Thanks,

Gua

From: Kinney, Michael D <michael.d.kinney@...>
Sent: Wednesday, September 14, 2022 9:52 AM
To: Sean Brogan <spbrogan@...>; devel@edk2.groups.io; Guo, Gua <gua.guo@...>; Kinney, Michael D <michael.d.kinney@...>
Cc: Sean Brogan <sean.brogan@...>; Michael Kubacki <mikuback@...>
Subject: RE: [edk2-devel] [PATCH v2] UnitTestFrameworkPkg: Add code coverage support for GCC

 

Does that pytool plugin support viewing the code coverage visually in C source files?

 

Either HTML or preferably an Visual Studio Code plugin?

 

Can it be updated to support VS compilers tool?

 

Mie

 

From: Sean Brogan <spbrogan@...>
Sent: Tuesday, September 13, 2022 6:18 PM
To: devel@edk2.groups.io; Guo, Gua <gua.guo@...>
Cc: Kinney, Michael D <michael.d.kinney@...>; Sean Brogan <sean.brogan@...>; Michael Kubacki <mikuback@...>
Subject: Re: [edk2-devel] [PATCH v2] UnitTestFrameworkPkg: Add code coverage support for GCC

 

Hi Gua Guo,

I would propose that we make this easier for both the local user and the CI system to get coverage metrics. 

Can you review this commit as it uses the same Edk2 plugins but adds code coverage support with GCC5:

Merged PR 5008: Initial implementation or code coverage on basecore u… · microsoft/mu_basecore@f6af51f (github.com)

 

Thanks

Sean

 

 

On 9/13/2022 6:01 PM, Guo, Gua wrote:

From: Gua Guo <gua.guo@...>
 
In order to collect code coverage after running executable
file, generate *.gcda and *.gcno file that require by lcov tool
to generate code coverage report.
 
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Sean Brogan <sean.brogan@...>
Cc: Bret Barkelew <Bret.Barkelew@...>
Cc: Michael Kubacki <mikuback@...>
Signed-off-by: Gua Guo <gua.guo@...>
---
 UnitTestFrameworkPkg/ReadMe.md                        | 116 +++++++++++++++++++-
 UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc |   2 +-
 2 files changed, 116 insertions(+), 2 deletions(-)
 
diff --git a/UnitTestFrameworkPkg/ReadMe.md b/UnitTestFrameworkPkg/ReadMe.md
index e696412cb3..93fdacfc4a 100644
--- a/UnitTestFrameworkPkg/ReadMe.md
+++ b/UnitTestFrameworkPkg/ReadMe.md
@@ -361,7 +361,7 @@ RUNNING TEST SUITE: Int Safe Conversions Test Suite
 ```
 
 
 
 You can also, if you are so inclined, read the output from the exact instance of the test that was run during
 
-`stuart_ci_build`. The ouput file can be found on a path that looks like:
 
+`stuart_ci_build`. The output file can be found on a path that looks like:
 
 
 
 `Build/<Package>/HostTest/<Arch>/<TestName>.<TestSuiteName>.<Arch>.result.xml`
 
 
 
@@ -399,6 +399,120 @@ CMOCKA_XML_FILE=<absolute or relative path to output file>
 
 
 This mode is used by the test running plugin to aggregate the results for CI test status reporting in the web view.
 
 
 
+### Enable Code Coverage for GCC host-based tests
 
+
 
+LCOV is an extension of GCOV, a GNU tool which provides information about what parts of a program are actually executed (i.e. "covered") while running a particular test case. The extension consists of a set of scripts which build on the textual GCOV output to implement it.
 
+
 
+Documentation for LCOV can be found here:
 
+https://lcov.readthedocs.io/
 
+
 
+You can follow below steps to generate your code coverage report.
 
+
 
+
 
+
 
+```bash
 
+user@linux_machine:~/_uefi$stuart_ci_build -c .pytool/CISettings.py TOOL_CHAIN_TAG=GCC5 -p MdePkg -t NOOPT
 
+...
 
+user@linux_machine:~/_uefi$lcov -c --rc lcov_branch_coverage=1 -o UnitTest.info -d Build/MdePkg/HostTest/NOOPT_GCC5/X64/MdePkg/
 
+Capturing coverage data from Build/MdePkg/HostTest/NOOPT_GCC5/X64/MdePkg/
 
+Found gcov version: 9.4.0
 
+Using intermediate gcov format
 
+Scanning Build/MdePkg/HostTest/NOOPT_GCC5/X64/MdePkg/ for .gcda files ...
 
+Found 38 data files in Build/MdePkg/HostTest/NOOPT_GCC5/X64/MdePkg/
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/RShiftU64.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/Math64.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/SafeString.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/SwapBytes32.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/CpuDeadLoop.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/MultU64x64.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/LongJump.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/SetJump.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/BitField.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/String.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/DivU64x32Remainder.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/X64/GccInline.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/MultU64x32.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/MultS64x64.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/LinkedList.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/LShiftU64.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/DivU64x32.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/SwapBytes16.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/Unaligned.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/CheckSum.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/CopyMem.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/MemLibGuid.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/CompareMemWrapper.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/SetMemWrapper.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/SetMem64Wrapper.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/MemLibGeneric.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/CopyMemWrapper.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/SetMem.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/ZeroMemWrapper.gcda
 
+Processing Library/BasePrintLib/BasePrintLib/OUTPUT/PrintLibInternal.gcda
 
+Processing Library/BasePrintLib/BasePrintLib/OUTPUT/PrintLib.gcda
 
+Processing Library/BaseSafeIntLib/BaseSafeIntLib/OUTPUT/SafeIntLib64.gcda
 
+Processing Library/BaseSafeIntLib/BaseSafeIntLib/OUTPUT/SafeIntLib.gcda
 
+Processing Test/UnitTest/Library/BaseLib/BaseLibUnitTestsHost/OUTPUT/Base64UnitTest.gcda
 
+Processing Test/UnitTest/Library/BaseLib/BaseLibUnitTestsHost/OUTPUT/AutoGen.gcda
 
+Processing Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibHost/OUTPUT/SafeIntLibUintnIntnUnitTests64.gcda
 
+Processing Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibHost/OUTPUT/TestBaseSafeIntLib.gcda
 
+Processing Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibHost/OUTPUT/AutoGen.gcda
 
+
 
+user@linux_machine:~/_uefi$genhtml UnitTest.info --branch-coverage -o Build/UnitTestReport
 
+
 
+Reading data file UnitTest.info
 
+Found 38 entries.
 
+Found common filename prefix "~/_uefi/MdePkg/Library"
 
+Writing .css and .png files.
 
+Generating output.
 
+Processing file ~/_uefi/Build/MdePkg/HostTest/NOOPT_GCC5/X64/MdePkg/Test/UnitTest/Library/BaseLib/BaseLibUnitTestsHost/DEBUG/AutoGen.c
 
+Processing file ~/_uefi/Build/MdePkg/HostTest/NOOPT_GCC5/X64/MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibHost/DEBUG/AutoGen.c
 
+Processing file BaseLib/Unaligned.c
 
+Processing file BaseLib/CheckSum.c
 
+Processing file BaseLib/BitField.c
 
+Processing file BaseLib/DivU64x32.c
 
+Processing file BaseLib/CpuDeadLoop.c
 
+Processing file BaseLib/LongJump.c
 
+Processing file BaseLib/MultU64x64.c
 
+Processing file BaseLib/RShiftU64.c
 
+Processing file BaseLib/SwapBytes32.c
 
+Processing file BaseLib/SwapBytes16.c
 
+Processing file BaseLib/SetJump.c
 
+Processing file BaseLib/LinkedList.c
 
+Processing file BaseLib/LShiftU64.c
 
+Processing file BaseLib/SafeString.c
 
+Processing file BaseLib/String.c
 
+Processing file BaseLib/DivU64x32Remainder.c
 
+Processing file BaseLib/MultS64x64.c
 
+Processing file BaseLib/MultU64x32.c
 
+Processing file BaseLib/Math64.c
 
+Processing file BaseLib/X64/GccInline.c
 
+Processing file BaseMemoryLib/SetMemWrapper.c
 
+Processing file BaseMemoryLib/CompareMemWrapper.c
 
+Processing file BaseMemoryLib/SetMem64Wrapper.c
 
+Processing file BaseMemoryLib/ZeroMemWrapper.c
 
+Processing file BaseMemoryLib/CopyMemWrapper.c
 
+Processing file BaseMemoryLib/CopyMem.c
 
+Processing file BaseMemoryLib/SetMem.c
 
+Processing file BaseMemoryLib/MemLibGuid.c
 
+Processing file BaseMemoryLib/MemLibGeneric.c
 
+Processing file BasePrintLib/PrintLib.c
 
+Processing file BasePrintLib/PrintLibInternal.c
 
+Processing file BaseSafeIntLib/SafeIntLib64.c
 
+Processing file BaseSafeIntLib/SafeIntLib.c
 
+Processing file ~/_uefi/MdePkg/Test/UnitTest/Library/BaseLib/Base64UnitTest.c
 
+Processing file ~/_uefi/MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLib.c
 
+Processing file ~/_uefi/MdePkg/Test/UnitTest/Library/BaseSafeIntLib/SafeIntLibUintnIntnUnitTests64.c
 
+Writing directory view page.
 
+Overall coverage rate:
 
+  lines......: 58.6% (2688 of 4589 lines)
 
+  functions..: 57.1% (249 of 436 functions)
 
+  branches...: 25.3% (1062 of 4195 branches)
 
+
 
+...
 
+
 
+```
 
+
 
 ### Important Note
 
 
 
 This works on both Windows and Linux, but is currently limited to x64 architectures. Working on getting others, but we
 
diff --git a/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc b/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
index 4dd8d4ac67..8623aecb33 100644
--- a/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
+++ b/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
@@ -19,7 +19,7 @@
   MemoryAllocationLib|UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.inf
 
 
 
 [BuildOptions]
 
-  GCC:*_*_*_CC_FLAGS = -fno-pie
 
+  GCC:*_*_*_CC_FLAGS = -fno-pie -ftest-coverage -fprofile-arcs
 
 !ifdef $(UNIT_TESTING_DEBUG)
 
   MSFT:*_*_*_CC_FLAGS  = -D UNIT_TESTING_DEBUG=1
 
   GCC:*_*_*_CC_FLAGS   = -D UNIT_TESTING_DEBUG=1
 


Re: [PATCH v2] UnitTestFrameworkPkg: Add code coverage support for GCC

Michael D Kinney
 

For VS builds, I have heard that OpenCppCoverage is a good option:

 

https://github.com/OpenCppCoverage/OpenCppCoverage

 

I think Sean has done some initial evaluation.  Would be great to see this enabled for local users for VS20xx tool chains.

 

Mike

 

 

From: Guo, Gua <gua.guo@...>
Sent: Tuesday, September 13, 2022 7:11 PM
To: Kinney, Michael D <michael.d.kinney@...>; Sean Brogan <spbrogan@...>; devel@edk2.groups.io
Cc: Sean Brogan <sean.brogan@...>; Michael Kubacki <mikuback@...>
Subject: RE: [edk2-devel] [PATCH v2] UnitTestFrameworkPkg: Add code coverage support for GCC

 

@Sean Brogan

 

I go through the code Merged PR 5008: Initial implementation or code coverage on basecore u… · microsoft/mu_basecore@f6af51f (github.com)

It looks good from my view point.

 

@Kinney, Michael D

Does that pytool plugin support viewing the code coverage visually in C source files? Yes

Either HTML or preferably an Visual Studio Code plugin? I think it can be supported by both based on below change. Due to VScode plugin is auto scan *.gcda and show the result in VScode source tree.
Merged PR 5008: Initial implementation or code coverage on basecore u… · microsoft/mu_basecore@f6af51f (github.com)

 

Flow for stuart_ci_build: (a) -> (b) -> (c) -> (d) -> (e) -> (f)

Flow for vscode extension Gcov Viewer - Visual Studio Marketplace:  (a) -> (b) -> (c) -> (d) -> (g)


(a) stuart_ci_build -p XXXPkg

(b) Call Edk2/.pytool/Plugin/HostUnitTestCompilerPlugin/HostUnitTestCompilerPlugin.py

(c) Call Edk2/BaseTools/Plugin/HostBasedUnitTestRunner/HostBasedUnitTestRunner.py

(d)       execute Build/XXXPkg/**/*Test* -> generate *.gcda files

(e)       use “lcov” tool to parse *.gcda

(f)        use “pycobertura” tool to generate index.html

(g) vscode extension to parse *.gcda and show it on source code directly.


Can it be updated to support VS compilers tool? No, currently I don’t find a good way to generate code coverage for MSVC compiler

 

Thanks,

Gua

From: Kinney, Michael D <michael.d.kinney@...>
Sent: Wednesday, September 14, 2022 9:52 AM
To: Sean Brogan <spbrogan@...>; devel@edk2.groups.io; Guo, Gua <gua.guo@...>; Kinney, Michael D <michael.d.kinney@...>
Cc: Sean Brogan <sean.brogan@...>; Michael Kubacki <mikuback@...>
Subject: RE: [edk2-devel] [PATCH v2] UnitTestFrameworkPkg: Add code coverage support for GCC

 

Does that pytool plugin support viewing the code coverage visually in C source files?

 

Either HTML or preferably an Visual Studio Code plugin?

 

Can it be updated to support VS compilers tool?

 

Mie

 

From: Sean Brogan <spbrogan@...>
Sent: Tuesday, September 13, 2022 6:18 PM
To: devel@edk2.groups.io; Guo, Gua <gua.guo@...>
Cc: Kinney, Michael D <michael.d.kinney@...>; Sean Brogan <sean.brogan@...>; Michael Kubacki <mikuback@...>
Subject: Re: [edk2-devel] [PATCH v2] UnitTestFrameworkPkg: Add code coverage support for GCC

 

Hi Gua Guo,

I would propose that we make this easier for both the local user and the CI system to get coverage metrics. 

Can you review this commit as it uses the same Edk2 plugins but adds code coverage support with GCC5:

Merged PR 5008: Initial implementation or code coverage on basecore u… · microsoft/mu_basecore@f6af51f (github.com)

 

Thanks

Sean

 

 

On 9/13/2022 6:01 PM, Guo, Gua wrote:

From: Gua Guo <gua.guo@...>
 
In order to collect code coverage after running executable
file, generate *.gcda and *.gcno file that require by lcov tool
to generate code coverage report.
 
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Sean Brogan <sean.brogan@...>
Cc: Bret Barkelew <Bret.Barkelew@...>
Cc: Michael Kubacki <mikuback@...>
Signed-off-by: Gua Guo <gua.guo@...>
---
 UnitTestFrameworkPkg/ReadMe.md                        | 116 +++++++++++++++++++-
 UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc |   2 +-
 2 files changed, 116 insertions(+), 2 deletions(-)
 
diff --git a/UnitTestFrameworkPkg/ReadMe.md b/UnitTestFrameworkPkg/ReadMe.md
index e696412cb3..93fdacfc4a 100644
--- a/UnitTestFrameworkPkg/ReadMe.md
+++ b/UnitTestFrameworkPkg/ReadMe.md
@@ -361,7 +361,7 @@ RUNNING TEST SUITE: Int Safe Conversions Test Suite
 ```
 
 
 
 You can also, if you are so inclined, read the output from the exact instance of the test that was run during
 
-`stuart_ci_build`. The ouput file can be found on a path that looks like:
 
+`stuart_ci_build`. The output file can be found on a path that looks like:
 
 
 
 `Build/<Package>/HostTest/<Arch>/<TestName>.<TestSuiteName>.<Arch>.result.xml`
 
 
 
@@ -399,6 +399,120 @@ CMOCKA_XML_FILE=<absolute or relative path to output file>
 
 
 This mode is used by the test running plugin to aggregate the results for CI test status reporting in the web view.
 
 
 
+### Enable Code Coverage for GCC host-based tests
 
+
 
+LCOV is an extension of GCOV, a GNU tool which provides information about what parts of a program are actually executed (i.e. "covered") while running a particular test case. The extension consists of a set of scripts which build on the textual GCOV output to implement it.
 
+
 
+Documentation for LCOV can be found here:
 
+https://lcov.readthedocs.io/
 
+
 
+You can follow below steps to generate your code coverage report.
 
+
 
+
 
+
 
+```bash
 
+user@linux_machine:~/_uefi$stuart_ci_build -c .pytool/CISettings.py TOOL_CHAIN_TAG=GCC5 -p MdePkg -t NOOPT
 
+...
 
+user@linux_machine:~/_uefi$lcov -c --rc lcov_branch_coverage=1 -o UnitTest.info -d Build/MdePkg/HostTest/NOOPT_GCC5/X64/MdePkg/
 
+Capturing coverage data from Build/MdePkg/HostTest/NOOPT_GCC5/X64/MdePkg/
 
+Found gcov version: 9.4.0
 
+Using intermediate gcov format
 
+Scanning Build/MdePkg/HostTest/NOOPT_GCC5/X64/MdePkg/ for .gcda files ...
 
+Found 38 data files in Build/MdePkg/HostTest/NOOPT_GCC5/X64/MdePkg/
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/RShiftU64.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/Math64.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/SafeString.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/SwapBytes32.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/CpuDeadLoop.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/MultU64x64.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/LongJump.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/SetJump.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/BitField.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/String.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/DivU64x32Remainder.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/X64/GccInline.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/MultU64x32.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/MultS64x64.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/LinkedList.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/LShiftU64.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/DivU64x32.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/SwapBytes16.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/Unaligned.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/CheckSum.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/CopyMem.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/MemLibGuid.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/CompareMemWrapper.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/SetMemWrapper.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/SetMem64Wrapper.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/MemLibGeneric.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/CopyMemWrapper.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/SetMem.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/ZeroMemWrapper.gcda
 
+Processing Library/BasePrintLib/BasePrintLib/OUTPUT/PrintLibInternal.gcda
 
+Processing Library/BasePrintLib/BasePrintLib/OUTPUT/PrintLib.gcda
 
+Processing Library/BaseSafeIntLib/BaseSafeIntLib/OUTPUT/SafeIntLib64.gcda
 
+Processing Library/BaseSafeIntLib/BaseSafeIntLib/OUTPUT/SafeIntLib.gcda
 
+Processing Test/UnitTest/Library/BaseLib/BaseLibUnitTestsHost/OUTPUT/Base64UnitTest.gcda
 
+Processing Test/UnitTest/Library/BaseLib/BaseLibUnitTestsHost/OUTPUT/AutoGen.gcda
 
+Processing Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibHost/OUTPUT/SafeIntLibUintnIntnUnitTests64.gcda
 
+Processing Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibHost/OUTPUT/TestBaseSafeIntLib.gcda
 
+Processing Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibHost/OUTPUT/AutoGen.gcda
 
+
 
+user@linux_machine:~/_uefi$genhtml UnitTest.info --branch-coverage -o Build/UnitTestReport
 
+
 
+Reading data file UnitTest.info
 
+Found 38 entries.
 
+Found common filename prefix "~/_uefi/MdePkg/Library"
 
+Writing .css and .png files.
 
+Generating output.
 
+Processing file ~/_uefi/Build/MdePkg/HostTest/NOOPT_GCC5/X64/MdePkg/Test/UnitTest/Library/BaseLib/BaseLibUnitTestsHost/DEBUG/AutoGen.c
 
+Processing file ~/_uefi/Build/MdePkg/HostTest/NOOPT_GCC5/X64/MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibHost/DEBUG/AutoGen.c
 
+Processing file BaseLib/Unaligned.c
 
+Processing file BaseLib/CheckSum.c
 
+Processing file BaseLib/BitField.c
 
+Processing file BaseLib/DivU64x32.c
 
+Processing file BaseLib/CpuDeadLoop.c
 
+Processing file BaseLib/LongJump.c
 
+Processing file BaseLib/MultU64x64.c
 
+Processing file BaseLib/RShiftU64.c
 
+Processing file BaseLib/SwapBytes32.c
 
+Processing file BaseLib/SwapBytes16.c
 
+Processing file BaseLib/SetJump.c
 
+Processing file BaseLib/LinkedList.c
 
+Processing file BaseLib/LShiftU64.c
 
+Processing file BaseLib/SafeString.c
 
+Processing file BaseLib/String.c
 
+Processing file BaseLib/DivU64x32Remainder.c
 
+Processing file BaseLib/MultS64x64.c
 
+Processing file BaseLib/MultU64x32.c
 
+Processing file BaseLib/Math64.c
 
+Processing file BaseLib/X64/GccInline.c
 
+Processing file BaseMemoryLib/SetMemWrapper.c
 
+Processing file BaseMemoryLib/CompareMemWrapper.c
 
+Processing file BaseMemoryLib/SetMem64Wrapper.c
 
+Processing file BaseMemoryLib/ZeroMemWrapper.c
 
+Processing file BaseMemoryLib/CopyMemWrapper.c
 
+Processing file BaseMemoryLib/CopyMem.c
 
+Processing file BaseMemoryLib/SetMem.c
 
+Processing file BaseMemoryLib/MemLibGuid.c
 
+Processing file BaseMemoryLib/MemLibGeneric.c
 
+Processing file BasePrintLib/PrintLib.c
 
+Processing file BasePrintLib/PrintLibInternal.c
 
+Processing file BaseSafeIntLib/SafeIntLib64.c
 
+Processing file BaseSafeIntLib/SafeIntLib.c
 
+Processing file ~/_uefi/MdePkg/Test/UnitTest/Library/BaseLib/Base64UnitTest.c
 
+Processing file ~/_uefi/MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLib.c
 
+Processing file ~/_uefi/MdePkg/Test/UnitTest/Library/BaseSafeIntLib/SafeIntLibUintnIntnUnitTests64.c
 
+Writing directory view page.
 
+Overall coverage rate:
 
+  lines......: 58.6% (2688 of 4589 lines)
 
+  functions..: 57.1% (249 of 436 functions)
 
+  branches...: 25.3% (1062 of 4195 branches)
 
+
 
+...
 
+
 
+```
 
+
 
 ### Important Note
 
 
 
 This works on both Windows and Linux, but is currently limited to x64 architectures. Working on getting others, but we
 
diff --git a/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc b/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
index 4dd8d4ac67..8623aecb33 100644
--- a/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
+++ b/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
@@ -19,7 +19,7 @@
   MemoryAllocationLib|UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.inf
 
 
 
 [BuildOptions]
 
-  GCC:*_*_*_CC_FLAGS = -fno-pie
 
+  GCC:*_*_*_CC_FLAGS = -fno-pie -ftest-coverage -fprofile-arcs
 
 !ifdef $(UNIT_TESTING_DEBUG)
 
   MSFT:*_*_*_CC_FLAGS  = -D UNIT_TESTING_DEBUG=1
 
   GCC:*_*_*_CC_FLAGS   = -D UNIT_TESTING_DEBUG=1
 


Re: [PATCH v2] UnitTestFrameworkPkg: Add code coverage support for GCC

Michael D Kinney
 

Does that mean that the patch under discussion here is still valuable for local users?

 

I want to make sure it is easy for local users to see the coverage as unit tests are implemented locally for Windows and Linux OSes.

 

The ci plugin you have looks valuable for CI testing to provide feedback to the entire community on coverage changes after an initial set of unit tests are in place.

 

Mike

 

From: Sean Brogan <spbrogan@...>
Sent: Tuesday, September 13, 2022 7:10 PM
To: Kinney, Michael D <michael.d.kinney@...>; devel@edk2.groups.io; Guo, Gua <gua.guo@...>
Cc: Sean Brogan <sean.brogan@...>; Michael Kubacki <mikuback@...>
Subject: Re: [edk2-devel] [PATCH v2] UnitTestFrameworkPkg: Add code coverage support for GCC

 

For local scenarios the plug-in generates the html report for viewing the c code with coverage annotations.  The intermediate files are available so I would think they could be loaded in all sorts of viewers but I haven’t tried. I have just used the html and it seemed acceptable. 

 

For ci the pipeline files have been updated to publish the data to the build. This allows using the online viewer to navigate c code and coverage. The html report is also uploaded and can be downloaded for local viewing. 

 

Regarding using visual studio tool chain/compilers we had discussed that for ci this is unnecessary ( since we already have coverage from gcc tool chain). For local users this is important. There is an easy tool you shared with me that gives similar results. I didn’t see a great way to integrate into the plug-in for auto invocation but I plan to write up usage details for local users. 

 

Thanks

Sean


From: Kinney, Michael D <michael.d.kinney@...>
Sent: Tuesday, September 13, 2022 6:51:43 PM
To: Sean Brogan <spbrogan@...>; devel@edk2.groups.io <devel@edk2.groups.io>; Guo, Gua <gua.guo@...>; Kinney, Michael D <michael.d.kinney@...>
Cc: Sean Brogan <sean.brogan@...>; Michael Kubacki <mikuback@...>
Subject: RE: [edk2-devel] [PATCH v2] UnitTestFrameworkPkg: Add code coverage support for GCC

 

Does that pytool plugin support viewing the code coverage visually in C source files?

 

Either HTML or preferably an Visual Studio Code plugin?

 

Can it be updated to support VS compilers tool?

 

Mie

 

From: Sean Brogan <spbrogan@...>
Sent: Tuesday, September 13, 2022 6:18 PM
To: devel@edk2.groups.io; Guo, Gua <gua.guo@...>
Cc: Kinney, Michael D <michael.d.kinney@...>; Sean Brogan <sean.brogan@...>; Michael Kubacki <mikuback@...>
Subject: Re: [edk2-devel] [PATCH v2] UnitTestFrameworkPkg: Add code coverage support for GCC

 

Hi Gua Guo,

I would propose that we make this easier for both the local user and the CI system to get coverage metrics. 

Can you review this commit as it uses the same Edk2 plugins but adds code coverage support with GCC5:

Merged PR 5008: Initial implementation or code coverage on basecore u… · microsoft/mu_basecore@f6af51f (github.com)

 

Thanks

Sean

 

 

On 9/13/2022 6:01 PM, Guo, Gua wrote:

From: Gua Guo <gua.guo@...>
 
In order to collect code coverage after running executable
file, generate *.gcda and *.gcno file that require by lcov tool
to generate code coverage report.
 
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Sean Brogan <sean.brogan@...>
Cc: Bret Barkelew <Bret.Barkelew@...>
Cc: Michael Kubacki <mikuback@...>
Signed-off-by: Gua Guo <gua.guo@...>
---
 UnitTestFrameworkPkg/ReadMe.md                        | 116 +++++++++++++++++++-
 UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc |   2 +-
 2 files changed, 116 insertions(+), 2 deletions(-)
 
diff --git a/UnitTestFrameworkPkg/ReadMe.md b/UnitTestFrameworkPkg/ReadMe.md
index e696412cb3..93fdacfc4a 100644
--- a/UnitTestFrameworkPkg/ReadMe.md
+++ b/UnitTestFrameworkPkg/ReadMe.md
@@ -361,7 +361,7 @@ RUNNING TEST SUITE: Int Safe Conversions Test Suite
 ```
 
 
 
 You can also, if you are so inclined, read the output from the exact instance of the test that was run during
 
-`stuart_ci_build`. The ouput file can be found on a path that looks like:
 
+`stuart_ci_build`. The output file can be found on a path that looks like:
 
 
 
 `Build/<Package>/HostTest/<Arch>/<TestName>.<TestSuiteName>.<Arch>.result.xml`
 
 
 
@@ -399,6 +399,120 @@ CMOCKA_XML_FILE=<absolute or relative path to output file>
 
 
 This mode is used by the test running plugin to aggregate the results for CI test status reporting in the web view.
 
 
 
+### Enable Code Coverage for GCC host-based tests
 
+
 
+LCOV is an extension of GCOV, a GNU tool which provides information about what parts of a program are actually executed (i.e. "covered") while running a particular test case. The extension consists of a set of scripts which build on the textual GCOV output to implement it.
 
+
 
+Documentation for LCOV can be found here:
 
+https://lcov.readthedocs.io/
 
+
 
+You can follow below steps to generate your code coverage report.
 
+
 
+
 
+
 
+```bash
 
+user@linux_machine:~/_uefi$stuart_ci_build -c .pytool/CISettings.py TOOL_CHAIN_TAG=GCC5 -p MdePkg -t NOOPT
 
+...
 
+user@linux_machine:~/_uefi$lcov -c --rc lcov_branch_coverage=1 -o UnitTest.info -d Build/MdePkg/HostTest/NOOPT_GCC5/X64/MdePkg/
 
+Capturing coverage data from Build/MdePkg/HostTest/NOOPT_GCC5/X64/MdePkg/
 
+Found gcov version: 9.4.0
 
+Using intermediate gcov format
 
+Scanning Build/MdePkg/HostTest/NOOPT_GCC5/X64/MdePkg/ for .gcda files ...
 
+Found 38 data files in Build/MdePkg/HostTest/NOOPT_GCC5/X64/MdePkg/
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/RShiftU64.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/Math64.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/SafeString.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/SwapBytes32.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/CpuDeadLoop.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/MultU64x64.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/LongJump.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/SetJump.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/BitField.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/String.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/DivU64x32Remainder.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/X64/GccInline.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/MultU64x32.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/MultS64x64.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/LinkedList.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/LShiftU64.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/DivU64x32.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/SwapBytes16.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/Unaligned.gcda
 
+Processing Library/BaseLib/UnitTestHostBaseLib/OUTPUT/CheckSum.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/CopyMem.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/MemLibGuid.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/CompareMemWrapper.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/SetMemWrapper.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/SetMem64Wrapper.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/MemLibGeneric.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/CopyMemWrapper.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/SetMem.gcda
 
+Processing Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/ZeroMemWrapper.gcda
 
+Processing Library/BasePrintLib/BasePrintLib/OUTPUT/PrintLibInternal.gcda
 
+Processing Library/BasePrintLib/BasePrintLib/OUTPUT/PrintLib.gcda
 
+Processing Library/BaseSafeIntLib/BaseSafeIntLib/OUTPUT/SafeIntLib64.gcda
 
+Processing Library/BaseSafeIntLib/BaseSafeIntLib/OUTPUT/SafeIntLib.gcda
 
+Processing Test/UnitTest/Library/BaseLib/BaseLibUnitTestsHost/OUTPUT/Base64UnitTest.gcda
 
+Processing Test/UnitTest/Library/BaseLib/BaseLibUnitTestsHost/OUTPUT/AutoGen.gcda
 
+Processing Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibHost/OUTPUT/SafeIntLibUintnIntnUnitTests64.gcda
 
+Processing Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibHost/OUTPUT/TestBaseSafeIntLib.gcda
 
+Processing Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibHost/OUTPUT/AutoGen.gcda
 
+
 
+user@linux_machine:~/_uefi$genhtml UnitTest.info --branch-coverage -o Build/UnitTestReport
 
+
 
+Reading data file UnitTest.info
 
+Found 38 entries.
 
+Found common filename prefix "~/_uefi/MdePkg/Library"
 
+Writing .css and .png files.
 
+Generating output.
 
+Processing file ~/_uefi/Build/MdePkg/HostTest/NOOPT_GCC5/X64/MdePkg/Test/UnitTest/Library/BaseLib/BaseLibUnitTestsHost/DEBUG/AutoGen.c
 
+Processing file ~/_uefi/Build/MdePkg/HostTest/NOOPT_GCC5/X64/MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibHost/DEBUG/AutoGen.c
 
+Processing file BaseLib/Unaligned.c
 
+Processing file BaseLib/CheckSum.c
 
+Processing file BaseLib/BitField.c
 
+Processing file BaseLib/DivU64x32.c
 
+Processing file BaseLib/CpuDeadLoop.c
 
+Processing file BaseLib/LongJump.c
 
+Processing file BaseLib/MultU64x64.c
 
+Processing file BaseLib/RShiftU64.c
 
+Processing file BaseLib/SwapBytes32.c
 
+Processing file BaseLib/SwapBytes16.c
 
+Processing file BaseLib/SetJump.c
 
+Processing file BaseLib/LinkedList.c
 
+Processing file BaseLib/LShiftU64.c
 
+Processing file BaseLib/SafeString.c
 
+Processing file BaseLib/String.c
 
+Processing file BaseLib/DivU64x32Remainder.c
 
+Processing file BaseLib/MultS64x64.c
 
+Processing file BaseLib/MultU64x32.c
 
+Processing file BaseLib/Math64.c
 
+Processing file BaseLib/X64/GccInline.c
 
+Processing file BaseMemoryLib/SetMemWrapper.c
 
+Processing file BaseMemoryLib/CompareMemWrapper.c
 
+Processing file BaseMemoryLib/SetMem64Wrapper.c
 
+Processing file BaseMemoryLib/ZeroMemWrapper.c
 
+Processing file BaseMemoryLib/CopyMemWrapper.c
 
+Processing file BaseMemoryLib/CopyMem.c
 
+Processing file BaseMemoryLib/SetMem.c
 
+Processing file BaseMemoryLib/MemLibGuid.c
 
+Processing file BaseMemoryLib/MemLibGeneric.c
 
+Processing file BasePrintLib/PrintLib.c
 
+Processing file BasePrintLib/PrintLibInternal.c
 
+Processing file BaseSafeIntLib/SafeIntLib64.c
 
+Processing file BaseSafeIntLib/SafeIntLib.c
 
+Processing file ~/_uefi/MdePkg/Test/UnitTest/Library/BaseLib/Base64UnitTest.c
 
+Processing file ~/_uefi/MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLib.c
 
+Processing file ~/_uefi/MdePkg/Test/UnitTest/Library/BaseSafeIntLib/SafeIntLibUintnIntnUnitTests64.c
 
+Writing directory view page.
 
+Overall coverage rate:
 
+  lines......: 58.6% (2688 of 4589 lines)
 
+  functions..: 57.1% (249 of 436 functions)
 
+  branches...: 25.3% (1062 of 4195 branches)
 
+
 
+...
 
+
 
+```
 
+
 
 ### Important Note
 
 
 
 This works on both Windows and Linux, but is currently limited to x64 architectures. Working on getting others, but we
 
diff --git a/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc b/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
index 4dd8d4ac67..8623aecb33 100644
--- a/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
+++ b/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
@@ -19,7 +19,7 @@
   MemoryAllocationLib|UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.inf
 
 
 
 [BuildOptions]
 
-  GCC:*_*_*_CC_FLAGS = -fno-pie
 
+  GCC:*_*_*_CC_FLAGS = -fno-pie -ftest-coverage -fprofile-arcs
 
 !ifdef $(UNIT_TESTING_DEBUG)
 
   MSFT:*_*_*_CC_FLAGS  = -D UNIT_TESTING_DEBUG=1
 
   GCC:*_*_*_CC_FLAGS   = -D UNIT_TESTING_DEBUG=1