Date   

Re: [PATCH v2 2/2] DynamicTablesPkg: Add an override for 16550 HID in SSDT

Alexei Fedorov
 

Reviewed-by: Alexei Fedorov <Alexei.Fedorov@...>


Re: [PATCH 1/2] MdeModulePkg/SataControllerDxe: Add support for drives in RAID mode

Albecki, Mateusz
 

Hello,

 

Sorry for getting in so late on the conversation but I want to make sure we are not going to break some platforms with this change. Excuse me if I am simply repeating what was being said before.

 

  1. We can’t have SataControllerDxe report supported for all raid interface devices on the market. As far as I know Intel RAID is rather special in that it implements AHCI interface underneath and if we encounter a RAID controller like that we will falsely claim that we support it. It’s hard to say whether this will have any consequences for the data integrity on the RAID array but at the very least we will prevent appropriate driver from binding to this RAID controller(potentially unbootable system).
  2. On newer Intel systems(not sure about G33) we have a dedicated RAID driver(RST driver) which will bind to integrated SATA in RAID mode. On such systems we have both RST driver and traditional SATA stack(SataControllerDxe, AtaAtapiPassThru etc) to allow runtime change between AHCI and RAID modes. If SataControllerDxe starts claiming SATA controller it will potentially make the system unbootable in RAID mode(if RAID is configured). What is more on those systems going through RAID config with volume managed by RST to standard AHCI config will corrupt RAID volumes. I can’t go into details on why is that but it has to do with how RST configures GPT partition.

 

In summary I don’t think we can add simple checks for RAID mode. Even adding a build flag could be potentially problematic since on desktop systems you never know what kind of controller user will plug in their slots. One potential solution would be to keep a list of controllers which do support AHCI interface even though they are reporting RAID class code but even then the solution could potentially break systems with both RST and AHCI stack present. Maybe we should have a platform provided protocol that would say whether AHCI drivers should load on such RAID controller?

 

Thanks,

Mateusz

From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Vitaly Cheptsov
Sent: Wednesday, December 16, 2020 10:31 AM
To: Kinney, Michael D <michael.d.kinney@...>
Cc: devel@edk2.groups.io; Wu, Hao A <hao.a.wu@...>; Ni, Ray <ray.ni@...>; Wang, Jian J <jian.j.wang@...>; Albecki, Mateusz <mateusz.albecki@...>; Laszlo Ersek <lersek@...>
Subject: Re: [edk2-devel] [PATCH 1/2] MdeModulePkg/SataControllerDxe: Add support for drives in RAID mode

 

Mike,

 

That’s right. And due to that interface being vendor-specific, Intel controllers work fine. I am not positive more logic is needed since it is opt-in. These patches are not new, and so far they worked reliably on a broad amount of systems for several years.

 

From what it looks like, you are strongly opposed to getting this land into EDK II mainline, since it is too specific (at least that is how I understand your arguments). If this is the case, I guess we could abandon these changes.

 

Best regards,

Vitaly

 

15 дек. 2020 г., в 23:01, Kinney, Michael D <michael.d.kinney@...> написал(а):

 

Another issue with this approach is that the formal PCI definition of this class code is in the following spec.

 

 

04h 00h RAID controller - vendor-specific interface

 

 

#define   PCI_CLASS_MASS_STORAGE_IDE    0x01

 

#define PCI_CLASS_MASS_STORAGE_SATADPA   0x06

#define   PCI_IF_MASS_STORAGE_SATA         0x00

#define   PCI_IF_MASS_STORAGE_AHCI         0x01

 

#define   PCI_CLASS_MASS_STORAGE_RAID   0x04

 

 

#define IS_PCI_IDE(_p)                IS_CLASS2 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_IDE)

#define IS_PCI_SATADPA(_p) IS_CLASS2 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_SATADPA)

#define IS_PCI_RAID(_p)               IS_CLASS2 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_RAID)

 

So the IS_PCI_RAID() macro checks for the RAID class code and the PCI spec states that the interface is vendor specific.  There is no guarantee what so ever that the controller that passes IS_PCI_RAID() check has a SATA interface.

 

There are lost of risks in using this macro to see if it is a SATA controller (even if enabled by a PCD).  You need to add more logic to even know it is safe to assume SATA registers.

 

Mike

 

 

 

 

 

From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Vitaly Cheptsov
Sent: Tuesday, December 15, 2020 11:47 AM
To: Kinney, Michael D <michael.d.kinney@...>
Cc: devel@edk2.groups.io; Wu, Hao A <hao.a.wu@...>; Ni, Ray <ray.ni@...>; Wang, Jian J <jian.j.wang@...>; Albecki, Mateusz <mateusz.albecki@...>; Laszlo Ersek <lersek@...>
Subject: Re: [edk2-devel] [PATCH 1/2] MdeModulePkg/SataControllerDxe: Add support for drives in RAID mode

 

Mike,

 

I understand that very well and thus the PCD rather than my original patch :)

 

Best,

Vitaly



On 15 Dec 2020, at 22:41, Kinney, Michael D <michael.d.kinney@...> wrote:

 

Vitaly,

 

I am concerned about platforms that use this driver with this change outside your use case.

 

Mike

 

From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Vitaly Cheptsov
Sent: Tuesday, December 15, 2020 11:40 AM
To: Kinney, Michael D <michael.d.kinney@...>
Cc: devel@edk2.groups.io; Wu, Hao A <hao.a.wu@...>; Ni, Ray <ray.ni@...>; Wang, Jian J <jian.j.wang@...>; Albecki, Mateusz <mateusz.albecki@...>; Laszlo Ersek <lersek@...>
Subject: Re: [edk2-devel] [PATCH 1/2] MdeModulePkg/SataControllerDxe: Add support for drives in RAID mode

 

As long as we do not write to a RAID array it will not cause any issues, and we do not. So I do not see an issue here.

 

Vitaly



On 15 Dec 2020, at 22:00, Kinney, Michael D <michael.d.kinney@...> wrote:

 

What about platforms that are in RAID mode and have configured a RAID set.  Your suggested change could potentially corrupt data on those different systems.

 

Mike

 

From: Vitaly Cheptsov <cheptsov@...> 
Sent: Tuesday, December 15, 2020 10:56 AM
To: Kinney, Michael D <michael.d.kinney@...>
Cc: devel@edk2.groups.io; Wu, Hao A <hao.a.wu@...>; Ni, Ray <ray.ni@...>; Wang, Jian J <jian.j.wang@...>; Albecki, Mateusz <mateusz.albecki@...>; Laszlo Ersek <lersek@...>
Subject: Re: [edk2-devel] [PATCH 1/2] MdeModulePkg/SataControllerDxe: Add support for drives in RAID mode

 

Not correct, these systems do not have hard RAID support or anything alike. It is standard G45 from what I remember. I believe the vendor simply left the firmware supplier defaults or something alike as there is a way to use IDE mode but nothing for AHCI.

 

Vitaly



On 15 Dec 2020, at 21:09, Kinney, Michael D <michael.d.kinney@...> wrote:

 

So those types of systems must have a RAID enabled FW driver.  Right?  So the drives could be configured as a RAID set and using the patch you suggest below could corrupt data.

 

It is difficult to support a change that could corrupt data.

 

Mike

 

From: Vitaly Cheptsov <cheptsov@...> 
Sent: Tuesday, December 15, 2020 9:44 AM
To: Kinney, Michael D <michael.d.kinney@...>
Cc: devel@edk2.groups.io; Wu, Hao A <hao.a.wu@...>; Ni, Ray <ray.ni@...>; Wang, Jian J <jian.j.wang@...>; Albecki, Mateusz <mateusz.albecki@...>; Laszlo Ersek <lersek@...>
Subject: Re: [edk2-devel] [PATCH 1/2] MdeModulePkg/SataControllerDxe: Add support for drives in RAID mode

 

Unfortunately not. That is basically the issue. When there is a preference, it is possible to ask the user to set it. However, for certain Dell machines, we have an issue with, it is not possible to select AHCI mode in the firmware preferences, and these users end up with unconfigurable RAID.

 

Best regards,

Vitaly



15 дек. 2020 г., в 20:41, Kinney, Michael D <michael.d.kinney@...> написал(а):

 

But do the systems allow the user to configure the FW that runs earlier?  Can you require to users to configure their platforms correctly?

 

Thanks,

 

Mike

 

From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Vitaly Cheptsov
Sent: Tuesday, December 15, 2020 9:34 AM
To: Kinney, Michael D <michael.d.kinney@...>
Cc: devel@edk2.groups.io; Wu, Hao A <hao.a.wu@...>; Ni, Ray <ray.ni@...>; Wang, Jian J <jian.j.wang@...>; Albecki, Mateusz <mateusz.albecki@...>; Laszlo Ersek <lersek@...>
Subject: Re: [edk2-devel] [PATCH 1/2] MdeModulePkg/SataControllerDxe: Add support for drives in RAID mode

 

Hi Michael,

 

I believe Intel SATA controllers have non-standard lockdown bits, which do not let you reconfigure them as soon as the initialisation is over. Since we start much later (outside of the firmware), we can no longer control this.

 

Best regards,

Vitaly




15 дек. 2020 г., в 19:58, Kinney, Michael D <michael.d.kinney@...> написал(а):

 

Hi Vitaly,

 

Can you please explain why the controller can not be configured in a non-RAID mode?

 

Thanks,

 

Mike

 

From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Vitaly Cheptsov
Sent: Tuesday, December 15, 2020 12:58 AM
To: Wu, Hao A <hao.a.wu@...>; devel@edk2.groups.io
Cc: Ni, Ray <ray.ni@...>; Wang, Jian J <jian.j.wang@...>; Albecki, Mateusz <mateusz.albecki@...>; Laszlo Ersek <lersek@...>; Kinney, Michael D <michael.d.kinney@...>
Subject: Re: [edk2-devel] [PATCH 1/2] MdeModulePkg/SataControllerDxe: Add support for drives in RAID mode

 

Hello,

 

1. Could you help to change the BZ tracker https://bugzilla.tianocore.org/show_bug.cgi?id=3118 to a "Tiano Feature Requests"?
For me, it looks more like a feature request.

 

Sure, done.

 

2. Could you help to include 'AtaAtapiPassThru' in the BZ tracker subject for better reference?

 

Also done.

 

3. For Patch 2/2, is there any reason to clear the bits:
EFI_ATA_PASS_THRU_ATTRIBUTES_PHYSICAL
EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL
If the drives are intended to be used as non-RAID devices, I think both the ATTRIBUTES_PHYSICAL & ATTRIBUTES_LOGICAL should be set for the controller according to the UEFI Spec.

 

I am not quite positive why this was needed (the patch was prepared a few months ago), but I will make a comment in V2 when we test it on real hardware. I think it was required to take the right path in the driver.

 

DuetPkg was removed from edk2.
If the change is specially for DUET use case, I am afraid we cannot accept this change.

 

This is not the DuetPkg from EDK II, but ours[1]. Thus your claim does not apply.

 

I agree it would be better to configure the platform so the SATA controller is in its non-RAID mode.

 

Agree, but in this case it is not feasible.

 

If the controller is in RAID mode, then the OS that is booted may have a SATA RAID driver
that can configure the drives in RAID mode.  Then, if the UEFI FW treats it as non RAID, it
may not be bootable, and configuration actions in UEFI may corrupt data on the RAID configured
drives.  For this reason, I am not in favor of adding a PCD.

 

Actually some operating systems have to introduce workarounds for this as well, and no, in this particular case the OS does not treat the drive as RAID either.

 

If there are no other review comments besides the attributes, I will proceed with V2 in the coming days.

 

Best regards,

Vitaly

 

 





15 дек. 2020 г., в 06:54, Kinney, Michael D <michael.d.kinney@...> написал(а):

 

I agree it would be better to configure the platform so the SATA controller is in its non-RAID mode.

If the controller is in RAID mode, then the OS that is booted may have a SATA RAID driver
that can configure the drives in RAID mode.  Then, if the UEFI FW treats it as non RAID, it
may not be bootable, and configuration actions in UEFI may corrupt data on the RAID configured
drives.  For this reason, I am not in favor of adding a PCD.

Mike




-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Wu, Hao A
Sent: Monday, December 14, 2020 5:53 PM
To: Ni, Ray <ray.ni@...>; devel@edk2.groups.io; cheptsov@...
Cc: Wang, Jian J <jian.j.wang@...>; Albecki, Mateusz <mateusz.albecki@...>; Laszlo Ersek <lersek@...>
Subject: Re: [edk2-devel] [PATCH 1/2] MdeModulePkg/SataControllerDxe: Add support for drives in RAID mode




-----Original Message-----
From: Ni, Ray <ray.ni@...>
Sent: Tuesday, December 15, 2020 9:45 AM
To: devel@edk2.groups.io; cheptsov@...
Cc: Wang, Jian J <jian.j.wang@...>; Wu, Hao A <hao.a.wu@...>;
Albecki, Mateusz <mateusz.albecki@...>; Laszlo Ersek
<lersek@...>
Subject: RE: [edk2-devel] [PATCH 1/2] MdeModulePkg/SataControllerDxe:
Add support for drives in RAID mode

DuetPkg was removed from edk2.
If the change is specially for DUET use case, I am afraid we cannot accept this
change.

Hao,
Can this change benefit a general use case?



Hello Ray,

My understanding to the proposed PCD is that drives behind a RAID mode SATA controller can be configured to working in
non-RAID mode (acting like individual drives).

As for the DuetPkg, below is a previous comment from Vitaly:
"there is no firmware preference for that (Hao: configure the controller to non-RAID mode). The firmware does not support
UEFI, and we are running through DuetPkg."

Best Regards,
Hao Wu






Thanks,
Ray




-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Vitaly
Cheptsov
Sent: Friday, December 11, 2020 5:25 PM
To: devel@edk2.groups.io
Cc: Vitaly Cheptsov <cheptsov@...>; Wang, Jian J
<jian.j.wang@...>; Wu, Hao A <hao.a.wu@...>; Albecki,
Mateusz <mateusz.albecki@...>; Laszlo Ersek <lersek@...>
Subject: [edk2-devel] [PATCH 1/2] MdeModulePkg/SataControllerDxe:

Add



support for drives in RAID mode

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

This resolves the problem of using drivers connected to Intel G33
builtin SATA controller when run from DuetPkg when it can only be
configured in RAID mode through the firmware settings.

Cc: Jian J Wang <jian.j.wang@...>
Cc: Hao A Wu <hao.a.wu@...>
Cc: Mateusz Albecki <mateusz.albecki@...>
Cc: Laszlo Ersek <lersek@...>
Signed-off-by: Vitaly Cheptsov <cheptsov@...>
---
MdeModulePkg/Bus/Pci/SataControllerDxe/SataController.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/MdeModulePkg/Bus/Pci/SataControllerDxe/SataController.c
b/MdeModulePkg/Bus/Pci/SataControllerDxe/SataController.c
index ab06e2833c..301335c967 100644
--- a/MdeModulePkg/Bus/Pci/SataControllerDxe/SataController.c
+++ b/MdeModulePkg/Bus/Pci/SataControllerDxe/SataController.c
@@ -324,7 +324,7 @@ SataControllerSupported (
    return EFI_UNSUPPORTED;
  }

-  if (IS_PCI_IDE (&PciData) || IS_PCI_SATADPA (&PciData)) {
+  if (IS_PCI_IDE (&PciData) || IS_PCI_SATADPA (&PciData) ||
+ IS_PCI_RAID (&PciData)) {
    return EFI_SUCCESS;
  }

@@ -465,7 +465,7 @@ SataControllerStart (
  if (IS_PCI_IDE (&PciData)) {
    Private->IdeInit.ChannelCount = IDE_MAX_CHANNEL;
    Private->DeviceCount          = IDE_MAX_DEVICES;
-  } else if (IS_PCI_SATADPA (&PciData)) {
+  } else if (IS_PCI_SATADPA (&PciData) || IS_PCI_RAID (&PciData)) {
    //
    // Read Ports Implemented(PI) to calculate max port number (0 based).
    //
--
2.24.3 (Apple Git-128)



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







 

 

 

 

 

---------------------------------------------------------------------
Intel Technology Poland sp. z o.o.
ul. Słowackiego 173 | 80-298 Gdańsk | Sąd Rejonowy Gdańsk Północ | VII Wydział Gospodarczy Krajowego Rejestru Sądowego - KRS 101882 | NIP 957-07-52-316 | Kapitał zakładowy 200.000 PLN.
Ta wiadomość wraz z załącznikami jest przeznaczona dla określonego adresata i może zawierać informacje poufne. W razie przypadkowego otrzymania tej wiadomości, prosimy o powiadomienie nadawcy oraz trwałe jej usunięcie; jakiekolwiek przeglądanie lub rozpowszechnianie jest zabronione.
This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). If you are not the intended recipient, please contact the sender and delete all copies; any review or distribution by others is strictly prohibited.


Re: [PATCH v2 1/2] DynamicTablesPkg: Don't use gEfiMdeModulePkgTokenSpaceGuid

Alexei Fedorov
 

Reviewed-by: Alexei Fedorov <Alexei.Fedorov@...>


Re: [PATCH v2 0/2] Add a Pcd to override the 16650 HID in SSDT

Alexei Fedorov
 

Reviewed-by: Alexei Fedorov <Alexei.Fedorov@...>


Re: [PATCH edk2-platforms v3 1/2] Drivers/OpTeeRpmb: Add an OP-TEE backed RPMB driver

Ilias Apalodimas
 

Hi Sami,

On Tue, Feb 02, 2021 at 10:40:32AM +0000, Sami Mujawar wrote:
Hi Ilias,

Please see my response inline marked [SAMI].

Regards,

Sami Mujawar

-----Original Message-----
From: Ilias Apalodimas <ilias.apalodimas@...>
Sent: 01 February 2021 02:01 PM
To: Sami Mujawar <Sami.Mujawar@...>
Cc: Sughosh Ganu <sughosh.ganu@...>; devel@edk2.groups.io; Ard Biesheuvel <Ard.Biesheuvel@...>; Leif Lindholm <leif@...>; Sahil Malhotra <sahil.malhotra@...>
Subject: Re: [PATCH edk2-platforms v3 1/2] Drivers/OpTeeRpmb: Add an OP-TEE backed RPMB driver

Hi Sami,


[...]
+STATIC
+EFI_STATUS
+ReadWriteRpmb (
+ UINTN SvcAct,
+ UINTN Addr,
+ UINTN NumBytes,
+ UINTN Offset
+ )
+{
+ ARM_SVC_ARGS SvcArgs;
+ EFI_STATUS Status;
+
+ ZeroMem (&SvcArgs, sizeof (SvcArgs));
+
+ SvcArgs.Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ_AARCH64;
+ SvcArgs.Arg1 = storage_id;
+ SvcArgs.Arg2 = 0;
+ SvcArgs.Arg3 = SvcAct;
+ SvcArgs.Arg4 = Addr;
+ SvcArgs.Arg5 = NumBytes;
+ SvcArgs.Arg6 = Offset;
+
+ ArmCallSvc (&SvcArgs);
+ if (SvcArgs.Arg3) {
+ DEBUG ((DEBUG_ERROR, "%a: Svc Call 0x%08x Addr: 0x%08x len: 0x%x Offset: 0x%x failed with 0x%x\n",
+ __func__, SvcAct, Addr, NumBytes, Offset, SvcArgs.Arg3));
+ }
+
+ switch (SvcArgs.Arg3) {
+ case ARM_SVC_SPM_RET_SUCCESS:
+ Status = EFI_SUCCESS;
+ break;
+
+ case ARM_SVC_SPM_RET_NOT_SUPPORTED:
+ Status = EFI_UNSUPPORTED;
+ break;
+
+ case ARM_SVC_SPM_RET_INVALID_PARAMS:
+ Status = EFI_INVALID_PARAMETER;
+ break;
+
+ case ARM_SVC_SPM_RET_DENIED:
+ Status = EFI_ACCESS_DENIED;
+ break;
+
+ case ARM_SVC_SPM_RET_NO_MEMORY:
+ Status = EFI_BAD_BUFFER_SIZE;
+ break;
+
+ default:
+ Status = EFI_ACCESS_DENIED;
+ }
[SAMI] Should the error handling here be updated similar to the FF-A StandaloneMmPkg patches?
[/SAMI]
I actually picked up the error handling from the previous non-FFA code.
I'll check what's on Sughosh latest patches and fix it if there are
any differences.
Looking at it again EFI_BAD_BUFFER_SIZE can change to indicate out of
memory properly anyway.
Had another look at this. This seems fine if I just change
EFI_BAD_BUFFER_SIZE -> EFI OUT_OF_RESOURCES because OP-TEE is only
using these errors from FFA. Eventually the OP-TEE code that launches
StMM today, will move to FFA and become a separate SP, so that will
naturally be handled once that's done. I don't see a point of adding
unused error cases.

[SAMI] Referring to the FFA specification, DEN0077A, v1.0, section 10.2 FFA_MSG_SEND_DIRECT_REQ and Table 10.8: FFA_ERROR encoding, I think the
error codes being handled above would be returned in SvcArgs.Arg2.
Hmm why ?

The message flow would be as follows:
- Caller sends FFA_MSG_SEND_DIRECT_REQ to the target endpoint.
- if the message does not reach the target endpoint, an error code from Table 10.8 may be returned in w2 (i.e. SvcArgs.Arg2)
That would be in the case you have a working TF-A implementation and the
message is never dispatched to the endpoint right?

The current driver is not implementing the whole range of that spec. The
communication between secure/non secure world is still based on the OP-TEE
messaging mechanism.
The only part that complies to the FFA spec is the communication between the
driver itself and OP-TEE.
- If the message reaches the target endpoint, then callee shall invoke one of the following interfaces:
* FFA_MSG_SEND_DIRECT_RESP
So what's happening here, is that we send an SVC with ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ_AARCH64.
The op-tee relevant code is located at ./core/arch/arm/kernel/stmm_sp.c
There's 2 things we handle right now on OP-TEE:
1. set the page permissions, after relocating the executable.
2. Read/Write data on our RPMB.

In both cases service_compose_direct_resp() is used to construct the response
and that set the return value on x3.


Regards
/Ilias

* FFA_INTERRUPT
* FFA_SUCCESS
This would mean that if the callee responds with FFA_MSG_SEND_DIRECT_RESP, the callee returned error/status code shall be in w/x3-w/x7 (which I think in this case may be in SvcArgs.Arg3).
[/SAMI]

Regards
/Ilias


Re: 回复: [edk2-devel] TianoCore Bug Triage - APAC / NAMO - Tue, 02/02/2021 6:30pm-7:30pm #cal-reminder

Niels Holm Olsen
 

Hi
Out of curiosity and to follow up on my bugreport 3186, I would like to know if it makes sense and is ok if I try to join the TianoCore Bug Triage tonight/early tomorrow.

I have taken the liberty of following the link to meetingsamer and it resulted in a download of a webex.exe. Running this and logging in with my name and email I were told the meeting hasn't started yet - which makes sense at this point of hour.

I have no experience in using this meeting-app but hope it works out ok. Please let me know if I need any further preparation to join.

Looking forward to listen in and maybe help explain my observations and concern regarding the potential bug if needed.

Niels Holm Olsen


How can I receive EAP packets?

梁宇飞 <yufei.liang@...>
 

Hello, I am Jiangbo technology R&D, using edkii to write EAP certified loader, I use EFI_ SIMPLE_ NETWORK.Transmit () to contract, want to use EFI_ SIMPLE_ NETWORK.Receive () to receive packets. It is found that ordinary IP packets can be received, but EAP packets cannot be received. How can I receive EAP package? I think there is a saying of hybrid mode in the program under windows. I want to know whether there is such a saying under EDK. In addition, I think EDK provides EFI_ EAP_ Protocol, I want to use this interface for user name and password authentication, but look at EFI_ EAP_ Protocol interface, do not know how to use, I would like to ask the relevant example code? Excuse me, everyone. I'm looking forward to your reply. Thank you very much!

 

Best Regards

Yufei liang

02/02/2021


[PATCH] IntelFsp2Pkg: Add YAML file generation support

Loo Tung Lun <tung.lun.loo@...>
 

Add support for YAML format file generation in addition
to current BSF structure. Configuration of YAML format
output will be supported by an open source ConfigEditor.

Reference to YAML code, test and ConfigEditor is at
https://github.com/joshloo/fsp_yaml_cfg/tree/master/Tools

A unit test is also added in Tests folder. This test compares
the generated yaml file against the expected output to know
if it is constructing the yaml data structure as expected.

Signed-off-by: Loo Tung Lun <tung.lun.loo@...>
---
IntelFsp2Pkg/Tools/FspDscBsf2Yaml.py | 875 +++++++++=
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
+++++++++++++++++++++++++++++++++++++++++
IntelFsp2Pkg/Tools/GenCfgOpt.py | 470 +++++++++=
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
+++++++++++++++++++++++++++++----------------------------------------------=
---------------------------------------------------------------------------=
-----------
IntelFsp2Pkg/Tools/Tests/ExpectedFspUpd.h | 16 +++++++++=
+++++++
IntelFsp2Pkg/Tools/Tests/ExpectedFspmUpd.h | 75 +++++++++=
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
IntelFsp2Pkg/Tools/Tests/ExpectedFspsUpd.h | 69 +++++++++=
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
IntelFsp2Pkg/Tools/Tests/ExpectedFsptUpd.h | 87 +++++++++=
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
+++
IntelFsp2Pkg/Tools/Tests/ExpectedOutput.bsf | 88 +++++++++=
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
++++
IntelFsp2Pkg/Tools/Tests/ExpectedOutput.yaml | 270 +++++++++=
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
++++++++++++++++++++++++++++++++++++
IntelFsp2Pkg/Tools/Tests/QemuFspPkg.dsc | 469 +++++++++=
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
++++++++++
IntelFsp2Pkg/Tools/Tests/test_yaml.py | 96 +++++++++=
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
++++++++++++
IntelFsp2Pkg/Tools/UserManuals/FspDscBsf2YamlUserManual.md | 39 +++++++++=
++++++++++++++++++++++++++++++
11 files changed, 2422 insertions(+), 132 deletions(-)

diff --git a/IntelFsp2Pkg/Tools/FspDscBsf2Yaml.py b/IntelFsp2Pkg/Tools/FspD=
scBsf2Yaml.py
new file mode 100644
index 0000000000..395fc2c526
--- /dev/null
+++ b/IntelFsp2Pkg/Tools/FspDscBsf2Yaml.py
@@ -0,0 +1,875 @@
+#!/usr/bin/env python=0D
+## @ FspDscBsf2Yaml.py=0D
+# This script convert FSP BSF format into DSC format=0D
+#=0D
+# Copyright(c) 2021, Intel Corporation. All rights reserved.<BR>=0D
+# SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+#=0D
+##=0D
+=0D
+import os=0D
+import re=0D
+import sys=0D
+from datetime import date=0D
+from collections import OrderedDict=0D
+from functools import reduce=0D
+=0D
+from GenCfgOpt import CGenCfgOpt=0D
+=0D
+__copyright_tmp__ =3D """## @file=0D
+#=0D
+# YAML CFGDATA %s File.=0D
+#=0D
+# Copyright(c) %4d, Intel Corporation. All rights reserved.<BR>=0D
+# SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+#=0D
+##=0D
+"""=0D
+=0D
+__copyright_dsc__ =3D """## @file=0D
+#=0D
+# Copyright (c) %04d, Intel Corporation. All rights reserved.<BR>=0D
+# SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+#=0D
+##=0D
+=0D
+[PcdsDynamicVpd.Upd]=0D
+ #=0D
+ # Global definitions in BSF=0D
+ # !BSF BLOCK:{NAME:"FSP UPD Configuration", VER:"0.1"}=0D
+ #=0D
+=0D
+"""=0D
+=0D
+=0D
+def Bytes2Val(Bytes):=0D
+ return reduce(lambda x, y: (x << 8) | y, Bytes[::-1])=0D
+=0D
+=0D
+class CFspBsf2Dsc:=0D
+=0D
+ def __init__(self, bsf_file):=0D
+ self.cfg_list =3D CFspBsf2Dsc.parse_bsf(bsf_file)=0D
+=0D
+ def get_dsc_lines(self):=0D
+ return CFspBsf2Dsc.generate_dsc(self.cfg_list)=0D
+=0D
+ def save_dsc(self, dsc_file):=0D
+ return CFspBsf2Dsc.generate_dsc(self.cfg_list, dsc_file)=0D
+=0D
+ @staticmethod=0D
+ def parse_bsf(bsf_file):=0D
+=0D
+ fd =3D open(bsf_file, 'r')=0D
+ bsf_txt =3D fd.read()=0D
+ fd.close()=0D
+=0D
+ find_list =3D []=0D
+ regex =3D re.compile(r'\s+Find\s+"(.*?)"(.*?)^\s+\$(.*?)\s+', re.S=
| re.MULTILINE)=0D
+ for match in regex.finditer(bsf_txt):=0D
+ find =3D match.group(1)=0D
+ name =3D match.group(3)=0D
+ if not name.endswith('_Revision'):=0D
+ raise Exception("Unexpected CFG item following 'Find' !")=
=0D
+ find_list.append((name, find))=0D
+=0D
+ idx =3D 0=0D
+ count =3D 0=0D
+ prefix =3D ''=0D
+ chk_dict =3D {}=0D
+ cfg_list =3D []=0D
+ cfg_temp =3D {'find': '', 'cname': '', 'length': 0, 'value': '0', =
'type': 'Reserved',=0D
+ 'embed': '', 'page': '', 'option': '', 'instance': 0}=
=0D
+ regex =3D re.compile(r'^\s+(\$(.*?)|Skip)\s+(\d+)\s+bytes(\s+\$_DE=
FAULT_\s+=3D\s+(.+?))?$',=0D
+ re.S | re.MULTILINE)=0D
+=0D
+ for match in regex.finditer(bsf_txt):=0D
+ dlen =3D int(match.group(3))=0D
+ if match.group(1) =3D=3D 'Skip':=0D
+ key =3D 'gPlatformFspPkgTokenSpaceGuid_BsfSkip%d' % idx=0D
+ val =3D ', '.join(['%02X' % ord(i) for i in '\x00' * dlen]=
)=0D
+ idx +=3D 1=0D
+ option =3D '$SKIP'=0D
+ else:=0D
+ key =3D match.group(2)=0D
+ val =3D match.group(5)=0D
+ option =3D ''=0D
+=0D
+ cfg_item =3D dict(cfg_temp)=0D
+ finds =3D [i for i in find_list if i[0] =3D=3D key]=0D
+ if len(finds) > 0:=0D
+ if count >=3D 1:=0D
+ # Append a dummy one=0D
+ cfg_item['cname'] =3D 'Dummy'=0D
+ cfg_list.append(dict(cfg_item))=0D
+ cfg_list[-1]['embed'] =3D '%s:TAG_%03X:END' % (prefix,=
ord(prefix[-1]))=0D
+ prefix =3D finds[0][1]=0D
+ cfg_item['embed'] =3D '%s:TAG_%03X:START' % (prefix, ord(p=
refix[-1]))=0D
+ cfg_item['find'] =3D prefix=0D
+ cfg_item['cname'] =3D 'Signature'=0D
+ cfg_item['length'] =3D len(finds[0][1])=0D
+ cfg_item['value'] =3D '0x%X' % Bytes2Val(finds[0][1].encod=
e('UTF-8'))=0D
+ cfg_list.append(dict(cfg_item))=0D
+ cfg_item =3D dict(cfg_temp)=0D
+ find_list.pop(0)=0D
+ count =3D 0=0D
+=0D
+ cfg_item['cname'] =3D key=0D
+ cfg_item['length'] =3D dlen=0D
+ cfg_item['value'] =3D val=0D
+ cfg_item['option'] =3D option=0D
+=0D
+ if key not in chk_dict.keys():=0D
+ chk_dict[key] =3D 0=0D
+ else:=0D
+ chk_dict[key] +=3D 1=0D
+ cfg_item['instance'] =3D chk_dict[key]=0D
+=0D
+ cfg_list.append(cfg_item)=0D
+ count +=3D 1=0D
+=0D
+ if prefix:=0D
+ cfg_item =3D dict(cfg_temp)=0D
+ cfg_item['cname'] =3D 'Dummy'=0D
+ cfg_item['embed'] =3D '%s:%03X:END' % (prefix, ord(prefix[-1])=
)=0D
+ cfg_list.append(cfg_item)=0D
+=0D
+ option_dict =3D {}=0D
+ selreg =3D re.compile(r'\s+Selection\s*(.+?)\s*,\s*"(.*?)"$', re.S=
| re.MULTILINE)=0D
+ regex =3D re.compile(r'^List\s&(.+?)$(.+?)^EndList$', re.S | re.MU=
LTILINE)=0D
+ for match in regex.finditer(bsf_txt):=0D
+ key =3D match.group(1)=0D
+ option_dict[key] =3D []=0D
+ for select in selreg.finditer(match.group(2)):=0D
+ option_dict[key].append((int(select.group(1), 0), select.g=
roup(2)))=0D
+=0D
+ chk_dict =3D {}=0D
+ pagereg =3D re.compile(r'^Page\s"(.*?)"$(.+?)^EndPage$', re.S | re=
.MULTILINE)=0D
+ for match in pagereg.finditer(bsf_txt):=0D
+ page =3D match.group(1)=0D
+ for line in match.group(2).splitlines():=0D
+ match =3D re.match(r'\s+(Combo|EditNum)\s\$(.+?),\s"(.*?)"=
,\s(.+?),$', line)=0D
+ if match:=0D
+ cname =3D match.group(2)=0D
+ if cname not in chk_dict.keys():=0D
+ chk_dict[cname] =3D 0=0D
+ else:=0D
+ chk_dict[cname] +=3D 1=0D
+ instance =3D chk_dict[cname]=0D
+ cfg_idxs =3D [i for i, j in enumerate(cfg_list) if j['=
cname'] =3D=3D cname and j['instance'] =3D=3D instance]=0D
+ if len(cfg_idxs) !=3D 1:=0D
+ raise Exception("Multiple CFG item '%s' found !" %=
cname)=0D
+ cfg_item =3D cfg_list[cfg_idxs[0]]=0D
+ cfg_item['page'] =3D page=0D
+ cfg_item['type'] =3D match.group(1)=0D
+ cfg_item['prompt'] =3D match.group(3)=0D
+ cfg_item['range'] =3D None=0D
+ if cfg_item['type'] =3D=3D 'Combo':=0D
+ cfg_item['option'] =3D option_dict[match.group(4)[=
1:]]=0D
+ elif cfg_item['type'] =3D=3D 'EditNum':=0D
+ cfg_item['option'] =3D match.group(4)=0D
+ match =3D re.match(r'\s+ Help\s"(.*?)"$', line)=0D
+ if match:=0D
+ cfg_item['help'] =3D match.group(1)=0D
+=0D
+ match =3D re.match(r'\s+"Valid\srange:\s(.*)"$', line)=0D
+ if match:=0D
+ parts =3D match.group(1).split()=0D
+ cfg_item['option'] =3D (=0D
+ (int(parts[0], 0), int(parts[2], 0), cfg_item['opt=
ion']))=0D
+=0D
+ return cfg_list=0D
+=0D
+ @staticmethod=0D
+ def generate_dsc(option_list, dsc_file=3DNone):=0D
+ dsc_lines =3D []=0D
+ header =3D '%s' % (__copyright_dsc__ % date.today().year)=0D
+ dsc_lines.extend(header.splitlines())=0D
+=0D
+ pages =3D []=0D
+ for cfg_item in option_list:=0D
+ if cfg_item['page'] and (cfg_item['page'] not in pages):=0D
+ pages.append(cfg_item['page'])=0D
+=0D
+ page_id =3D 0=0D
+ for page in pages:=0D
+ dsc_lines.append(' # !BSF PAGES:{PG%02X::"%s"}' % (page_id, p=
age))=0D
+ page_id +=3D 1=0D
+ dsc_lines.append('')=0D
+=0D
+ last_page =3D ''=0D
+ for option in option_list:=0D
+ dsc_lines.append('')=0D
+ default =3D option['value']=0D
+ pos =3D option['cname'].find('_')=0D
+ name =3D option['cname'][pos + 1:]=0D
+=0D
+ if option['find']:=0D
+ dsc_lines.append(' # !BSF FIND:{%s}' % option['find'])=0D
+ dsc_lines.append('')=0D
+=0D
+ if option['instance'] > 0:=0D
+ name =3D name + '_%s' % option['instance']=0D
+=0D
+ if option['embed']:=0D
+ dsc_lines.append(' # !HDR EMBED:{%s}' % option['embed'])=
=0D
+=0D
+ if option['type'] =3D=3D 'Reserved':=0D
+ dsc_lines.append(' # !BSF NAME:{Reserved} TYPE:{Reserved}=
')=0D
+ if option['option'] =3D=3D '$SKIP':=0D
+ dsc_lines.append(' # !BSF OPTION:{$SKIP}')=0D
+ else:=0D
+ prompt =3D option['prompt']=0D
+=0D
+ if last_page !=3D option['page']:=0D
+ last_page =3D option['page']=0D
+ dsc_lines.append(' # !BSF PAGE:{PG%02X}' % (pages.ind=
ex(option['page'])))=0D
+=0D
+ if option['type'] =3D=3D 'Combo':=0D
+ dsc_lines.append(' # !BSF NAME:{%s} TYPE:{%s}' %=0D
+ (prompt, option['type']))=0D
+ ops =3D []=0D
+ for val, text in option['option']:=0D
+ ops.append('0x%x:%s' % (val, text))=0D
+ dsc_lines.append(' # !BSF OPTION:{%s}' % (', '.join(o=
ps)))=0D
+ elif option['type'] =3D=3D 'EditNum':=0D
+ cfg_len =3D option['length']=0D
+ if ',' in default and cfg_len > 8:=0D
+ dsc_lines.append(' # !BSF NAME:{%s} TYPE:{Table}'=
% (prompt))=0D
+ if cfg_len > 16:=0D
+ cfg_len =3D 16=0D
+ ops =3D []=0D
+ for i in range(cfg_len):=0D
+ ops.append('%X:1:HEX' % i)=0D
+ dsc_lines.append(' # !BSF OPTION:{%s}' % (', '.jo=
in(ops)))=0D
+ else:=0D
+ dsc_lines.append(=0D
+ ' # !BSF NAME:{%s} TYPE:{%s, %s,(0x%X, 0x%X)}=
' %=0D
+ (prompt, option['type'], option['option'][2],=
=0D
+ option['option'][0], option['option'][1]))=0D
+ dsc_lines.append(' # !BSF HELP:{%s}' % option['help'])=0D
+=0D
+ if ',' in default:=0D
+ default =3D '{%s}' % default=0D
+ dsc_lines.append(' gCfgData.%-30s | * | 0x%04X | %s' %=0D
+ (name, option['length'], default))=0D
+=0D
+ if dsc_file:=0D
+ fd =3D open(dsc_file, 'w')=0D
+ fd.write('\n'.join(dsc_lines))=0D
+ fd.close()=0D
+=0D
+ return dsc_lines=0D
+=0D
+=0D
+class CFspDsc2Yaml():=0D
+=0D
+ def __init__(self):=0D
+ self._Hdr_key_list =3D ['EMBED', 'STRUCT']=0D
+ self._Bsf_key_list =3D ['NAME', 'HELP', 'TYPE', 'PAGE', 'PAGES', '=
OPTION',=0D
+ 'CONDITION', 'ORDER', 'MARKER', 'SUBT', 'FIE=
LD', 'FIND']=0D
+ self.gen_cfg_data =3D None=0D
+ self.cfg_reg_exp =3D re.compile(r"^([_a-zA-Z0-9$\(\)]+)\s*\|\s*(0x=
[0-9A-F]+|\*)\s*\|"=0D
+ + r"\s*(\d+|0x[0-9a-fA-F]+)\s*\|\s*(=
.+)")=0D
+ self.bsf_reg_exp =3D re.compile(r"(%s):{(.+?)}(?:$|\s+)" % '|'.joi=
n(self._Bsf_key_list))=0D
+ self.hdr_reg_exp =3D re.compile(r"(%s):{(.+?)}" % '|'.join(self._H=
dr_key_list))=0D
+ self.prefix =3D ''=0D
+ self.unused_idx =3D 0=0D
+ self.offset =3D 0=0D
+ self.base_offset =3D 0=0D
+=0D
+ def load_config_data_from_dsc(self, file_name):=0D
+ """=0D
+ Load and parse a DSC CFGDATA file.=0D
+ """=0D
+ gen_cfg_data =3D CGenCfgOpt('FSP')=0D
+ if file_name.endswith('.dsc'):=0D
+ # if gen_cfg_data.ParseDscFileYaml(file_name, '') !=3D 0:=0D
+ if gen_cfg_data.ParseDscFile(file_name, '') !=3D 0:=0D
+ raise Exception('DSC file parsing error !')=0D
+ if gen_cfg_data.CreateVarDict() !=3D 0:=0D
+ raise Exception('DSC variable creation error !')=0D
+ else:=0D
+ raise Exception('Unsupported file "%s" !' % file_name)=0D
+ gen_cfg_data.UpdateDefaultValue()=0D
+ self.gen_cfg_data =3D gen_cfg_data=0D
+=0D
+ def print_dsc_line(self):=0D
+ """=0D
+ Debug function to print all DSC lines.=0D
+ """=0D
+ for line in self.gen_cfg_data._DscLines:=0D
+ print(line)=0D
+=0D
+ def format_value(self, field, text, indent=3D''):=0D
+ """=0D
+ Format a CFGDATA item into YAML format.=0D
+ """=0D
+ if(not text.startswith('!expand')) and (': ' in text):=0D
+ tgt =3D ':' if field =3D=3D 'option' else '- '=0D
+ text =3D text.replace(': ', tgt)=0D
+ lines =3D text.splitlines()=0D
+ if len(lines) =3D=3D 1 and field !=3D 'help':=0D
+ return text=0D
+ else:=0D
+ return '>\n ' + '\n '.join([indent + i.lstrip() for i in l=
ines])=0D
+=0D
+ def reformat_pages(self, val):=0D
+ # Convert XXX:YYY into XXX::YYY format for page definition=0D
+ parts =3D val.split(',')=0D
+ if len(parts) <=3D 1:=0D
+ return val=0D
+=0D
+ new_val =3D []=0D
+ for each in parts:=0D
+ nodes =3D each.split(':')=0D
+ if len(nodes) =3D=3D 2:=0D
+ each =3D '%s::%s' % (nodes[0], nodes[1])=0D
+ new_val.append(each)=0D
+ ret =3D ','.join(new_val)=0D
+ return ret=0D
+=0D
+ def reformat_struct_value(self, utype, val):=0D
+ # Convert DSC UINT16/32/64 array into new format by=0D
+ # adding prefix 0:0[WDQ] to provide hint to the array format=0D
+ if utype in ['UINT16', 'UINT32', 'UINT64']:=0D
+ if val and val[0] =3D=3D '{' and val[-1] =3D=3D '}':=0D
+ if utype =3D=3D 'UINT16':=0D
+ unit =3D 'W'=0D
+ elif utype =3D=3D 'UINT32':=0D
+ unit =3D 'D'=0D
+ else:=0D
+ unit =3D 'Q'=0D
+ val =3D '{ 0:0%s, %s }' % (unit, val[1:-1])=0D
+ return val=0D
+=0D
+ def process_config(self, cfg):=0D
+ if 'page' in cfg:=0D
+ cfg['page'] =3D self.reformat_pages(cfg['page'])=0D
+=0D
+ if 'struct' in cfg:=0D
+ cfg['value'] =3D self.reformat_struct_value(cfg['struct'], cfg=
['value'])=0D
+=0D
+ def parse_dsc_line(self, dsc_line, config_dict, init_dict, include):=0D
+ """=0D
+ Parse a line in DSC and update the config dictionary accordingly.=
=0D
+ """=0D
+ init_dict.clear()=0D
+ match =3D re.match(r'g(CfgData|\w+FspPkgTokenSpaceGuid)\.(.+)', ds=
c_line)=0D
+ if match:=0D
+ match =3D self.cfg_reg_exp.match(match.group(2))=0D
+ if not match:=0D
+ return False=0D
+ config_dict['cname'] =3D self.prefix + match.group(1)=0D
+ value =3D match.group(4).strip()=0D
+ length =3D match.group(3).strip()=0D
+ config_dict['length'] =3D length=0D
+ config_dict['value'] =3D value=0D
+ if match.group(2) =3D=3D '*':=0D
+ self.offset +=3D int(length, 0)=0D
+ else:=0D
+ org_offset =3D int(match.group(2), 0)=0D
+ if org_offset =3D=3D 0:=0D
+ self.base_offset =3D self.offset=0D
+ offset =3D org_offset + self.base_offset=0D
+ if self.offset !=3D offset:=0D
+ if offset > self.offset:=0D
+ init_dict['padding'] =3D offset - self.offset=0D
+ self.offset =3D offset + int(length, 0)=0D
+ return True=0D
+=0D
+ match =3D re.match(r"^\s*#\s+!([<>])\s+include\s+(.+)", dsc_line)=
=0D
+ if match and len(config_dict) =3D=3D 0:=0D
+ # !include should not be inside a config field=0D
+ # if so, do not convert include into YAML=0D
+ init_dict =3D dict(config_dict)=0D
+ config_dict.clear()=0D
+ config_dict['cname'] =3D '$ACTION'=0D
+ if match.group(1) =3D=3D '<':=0D
+ config_dict['include'] =3D match.group(2)=0D
+ else:=0D
+ config_dict['include'] =3D ''=0D
+ return True=0D
+=0D
+ match =3D re.match(r"^\s*#\s+(!BSF|!HDR)\s+(.+)", dsc_line)=0D
+ if not match:=0D
+ return False=0D
+=0D
+ remaining =3D match.group(2)=0D
+ if match.group(1) =3D=3D '!BSF':=0D
+ result =3D self.bsf_reg_exp.findall(remaining)=0D
+ if not result:=0D
+ return False=0D
+=0D
+ for each in result:=0D
+ key =3D each[0].lower()=0D
+ val =3D each[1]=0D
+ if key =3D=3D 'field':=0D
+ name =3D each[1]=0D
+ if ':' not in name:=0D
+ raise Exception('Incorrect bit field format !')=0D
+ parts =3D name.split(':')=0D
+ config_dict['length'] =3D parts[1]=0D
+ config_dict['cname'] =3D '@' + parts[0]=0D
+ return True=0D
+ elif key in ['pages', 'page', 'find']:=0D
+ init_dict =3D dict(config_dict)=0D
+ config_dict.clear()=0D
+ config_dict['cname'] =3D '$ACTION'=0D
+ if key =3D=3D 'find':=0D
+ config_dict['find'] =3D val=0D
+ else:=0D
+ config_dict['page'] =3D val=0D
+ return True=0D
+ elif key =3D=3D 'subt':=0D
+ config_dict.clear()=0D
+ parts =3D each[1].split(':')=0D
+ tmp_name =3D parts[0][:-5]=0D
+ if tmp_name =3D=3D 'CFGHDR':=0D
+ cfg_tag =3D '_$FFF_'=0D
+ sval =3D '!expand { %s_TMPL : [ ' % tmp_name + '%s=
, %s, ' % (parts[1], cfg_tag) \=0D
+ + ', '.join(parts[2:]) + ' ] }'=0D
+ else:=0D
+ sval =3D '!expand { %s_TMPL : [ ' % tmp_name + ', =
'.join(parts[1:]) + ' ] }'=0D
+ config_dict.clear()=0D
+ config_dict['cname'] =3D tmp_name=0D
+ config_dict['expand'] =3D sval=0D
+ return True=0D
+ else:=0D
+ if key in ['name', 'help', 'option'] and val.startswit=
h('+'):=0D
+ val =3D config_dict[key] + '\n' + val[1:]=0D
+ if val.strip() =3D=3D '':=0D
+ val =3D "''"=0D
+ config_dict[key] =3D val=0D
+=0D
+ else:=0D
+ match =3D self.hdr_reg_exp.match(remaining)=0D
+ if not match:=0D
+ return False=0D
+ key =3D match.group(1)=0D
+ remaining =3D match.group(2)=0D
+ if key =3D=3D 'EMBED':=0D
+ parts =3D remaining.split(':')=0D
+ names =3D parts[0].split(',')=0D
+ if parts[-1] =3D=3D 'END':=0D
+ prefix =3D '>'=0D
+ else:=0D
+ prefix =3D '<'=0D
+ skip =3D False=0D
+ if parts[1].startswith('TAG_'):=0D
+ tag_txt =3D '%s:%s' % (names[0], parts[1])=0D
+ else:=0D
+ tag_txt =3D names[0]=0D
+ if parts[2] in ['START', 'END']:=0D
+ if names[0] =3D=3D 'PCIE_RP_PIN_CTRL[]':=0D
+ skip =3D True=0D
+ else:=0D
+ tag_txt =3D '%s:%s' % (names[0], parts[1])=0D
+ if not skip:=0D
+ config_dict.clear()=0D
+ config_dict['cname'] =3D prefix + tag_txt=0D
+ return True=0D
+=0D
+ if key =3D=3D 'STRUCT':=0D
+ text =3D remaining.strip()=0D
+ config_dict[key.lower()] =3D text=0D
+=0D
+ return False=0D
+=0D
+ def process_template_lines(self, lines):=0D
+ """=0D
+ Process a line in DSC template section.=0D
+ """=0D
+ template_name =3D ''=0D
+ bsf_temp_dict =3D OrderedDict()=0D
+ temp_file_dict =3D OrderedDict()=0D
+ include_file =3D ['.']=0D
+=0D
+ for line in lines:=0D
+ match =3D re.match(r"^\s*#\s+!([<>])\s+include\s+(.+)", line)=
=0D
+ if match:=0D
+ if match.group(1) =3D=3D '<':=0D
+ include_file.append(match.group(2))=0D
+ else:=0D
+ include_file.pop()=0D
+=0D
+ match =3D re.match(r"^\s*#\s+(!BSF)\s+DEFT:{(.+?):(START|END)}=
", line)=0D
+ if match:=0D
+ if match.group(3) =3D=3D 'START' and not template_name:=0D
+ template_name =3D match.group(2).strip()=0D
+ temp_file_dict[template_name] =3D list(include_file)=0D
+ bsf_temp_dict[template_name] =3D []=0D
+ if match.group(3) =3D=3D 'END' and (template_name =3D=3D m=
atch.group(2).strip()) \=0D
+ and template_name:=0D
+ template_name =3D ''=0D
+ else:=0D
+ if template_name:=0D
+ bsf_temp_dict[template_name].append(line)=0D
+ return bsf_temp_dict, temp_file_dict=0D
+=0D
+ def process_option_lines(self, lines):=0D
+ """=0D
+ Process a line in DSC config section.=0D
+ """=0D
+ cfgs =3D []=0D
+ struct_end =3D False=0D
+ config_dict =3D dict()=0D
+ init_dict =3D dict()=0D
+ include =3D ['']=0D
+ for line in lines:=0D
+ ret =3D self.parse_dsc_line(line, config_dict, init_dict, incl=
ude)=0D
+ if ret:=0D
+ if 'padding' in init_dict:=0D
+ num =3D init_dict['padding']=0D
+ init_dict.clear()=0D
+ padding_dict =3D {}=0D
+ cfgs.append(padding_dict)=0D
+ padding_dict['cname'] =3D 'UnusedUpdSpace%d' % self.un=
used_idx=0D
+ padding_dict['length'] =3D '0x%x' % num=0D
+ padding_dict['value'] =3D '{ 0 }'=0D
+ self.unused_idx +=3D 1=0D
+=0D
+ if cfgs and cfgs[-1]['cname'][0] !=3D '@' and config_dict[=
'cname'][0] =3D=3D '@':=0D
+ # it is a bit field, mark the previous one as virtual=
=0D
+ cname =3D cfgs[-1]['cname']=0D
+ new_cfg =3D dict(cfgs[-1])=0D
+ new_cfg['cname'] =3D '@$STRUCT'=0D
+ cfgs[-1].clear()=0D
+ cfgs[-1]['cname'] =3D cname=0D
+ cfgs.append(new_cfg)=0D
+=0D
+ if cfgs and cfgs[-1]['cname'] =3D=3D 'CFGHDR' and config_d=
ict['cname'][0] =3D=3D '<':=0D
+ # swap CfgHeader and the CFG_DATA order=0D
+ if ':' in config_dict['cname']:=0D
+ # replace the real TAG for CFG_DATA=0D
+ cfgs[-1]['expand'] =3D cfgs[-1]['expand'].replace(=
=0D
+ '_$FFF_', '0x%s' %=0D
+ config_dict['cname'].split(':')[1][4:])=0D
+ cfgs.insert(-1, config_dict)=0D
+ else:=0D
+ self.process_config(config_dict)=0D
+ if struct_end:=0D
+ struct_end =3D False=0D
+ cfgs.insert(-1, config_dict)=0D
+ else:=0D
+ cfgs.append(config_dict)=0D
+ if config_dict['cname'][0] =3D=3D '>':=0D
+ struct_end =3D True=0D
+=0D
+ config_dict =3D dict(init_dict)=0D
+ return cfgs=0D
+=0D
+ def variable_fixup(self, each):=0D
+ """=0D
+ Fix up some variable definitions for SBL.=0D
+ """=0D
+ key =3D each=0D
+ val =3D self.gen_cfg_data._MacroDict[each]=0D
+ return key, val=0D
+=0D
+ def template_fixup(self, tmp_name, tmp_list):=0D
+ """=0D
+ Fix up some special config templates for SBL=0D
+ """=0D
+ return=0D
+=0D
+ def config_fixup(self, cfg_list):=0D
+ """=0D
+ Fix up some special config items for SBL.=0D
+ """=0D
+=0D
+ # Insert FSPT_UPD/FSPM_UPD/FSPS_UPD tag so as to create C strcture=
=0D
+ idxs =3D []=0D
+ for idx, cfg in enumerate(cfg_list):=0D
+ if cfg['cname'].startswith('<FSP_UPD_HEADER'):=0D
+ idxs.append(idx)=0D
+=0D
+ if len(idxs) !=3D 3:=0D
+ return=0D
+=0D
+ # Handle insert backwards so that the index does not change in the=
loop=0D
+ fsp_comp =3D 'SMT'=0D
+ idx_comp =3D 0=0D
+ for idx in idxs[::-1]:=0D
+ # Add current FSP?_UPD start tag=0D
+ cfgfig_dict =3D {}=0D
+ cfgfig_dict['cname'] =3D '<FSP%s_UPD' % fsp_comp[idx_comp]=0D
+ cfg_list.insert(idx, cfgfig_dict)=0D
+ if idx_comp < 2:=0D
+ # Add previous FSP?_UPD end tag=0D
+ cfgfig_dict =3D {}=0D
+ cfgfig_dict['cname'] =3D '>FSP%s_UPD' % fsp_comp[idx_comp =
+ 1]=0D
+ cfg_list.insert(idx, cfgfig_dict)=0D
+ idx_comp +=3D 1=0D
+=0D
+ # Add final FSPS_UPD end tag=0D
+ cfgfig_dict =3D {}=0D
+ cfgfig_dict['cname'] =3D '>FSP%s_UPD' % fsp_comp[0]=0D
+ cfg_list.append(cfgfig_dict)=0D
+=0D
+ return=0D
+=0D
+ def get_section_range(self, section_name):=0D
+ """=0D
+ Extract line number range from config file for a given section nam=
e.=0D
+ """=0D
+ start =3D -1=0D
+ end =3D -1=0D
+ for idx, line in enumerate(self.gen_cfg_data._DscLines):=0D
+ if start < 0 and line.startswith('[%s]' % section_name):=0D
+ start =3D idx=0D
+ elif start >=3D 0 and line.startswith('['):=0D
+ end =3D idx=0D
+ break=0D
+ if start =3D=3D -1:=0D
+ start =3D 0=0D
+ if end =3D=3D -1:=0D
+ end =3D len(self.gen_cfg_data._DscLines)=0D
+ return start, end=0D
+=0D
+ def normalize_file_name(self, file, is_temp=3DFalse):=0D
+ """=0D
+ Normalize file name convention so that it is consistent.=0D
+ """=0D
+ if file.endswith('.dsc'):=0D
+ file =3D file[:-4] + '.yaml'=0D
+ dir_name =3D os.path.dirname(file)=0D
+ base_name =3D os.path.basename(file)=0D
+ if is_temp:=0D
+ if 'Template_' not in file:=0D
+ base_name =3D base_name.replace('Template', 'Template_')=0D
+ else:=0D
+ if 'CfgData_' not in file:=0D
+ base_name =3D base_name.replace('CfgData', 'CfgData_')=0D
+ if dir_name:=0D
+ path =3D dir_name + '/' + base_name=0D
+ else:=0D
+ path =3D base_name=0D
+ return path=0D
+=0D
+ def output_variable(self):=0D
+ """=0D
+ Output variable block into a line list.=0D
+ """=0D
+ lines =3D []=0D
+ for each in self.gen_cfg_data._MacroDict:=0D
+ key, value =3D self.variable_fixup(each)=0D
+ lines.append('%-30s : %s' % (key, value))=0D
+ return lines=0D
+=0D
+ def output_template(self):=0D
+ """=0D
+ Output template block into a line list.=0D
+ """=0D
+ self.offset =3D 0=0D
+ self.base_offset =3D 0=0D
+ start, end =3D self.get_section_range('PcdsDynamicVpd.Tmp')=0D
+ bsf_temp_dict, temp_file_dict =3D self.process_template_lines(self=
.gen_cfg_data._DscLines[start:end])=0D
+ template_dict =3D dict()=0D
+ lines =3D []=0D
+ file_lines =3D {}=0D
+ last_file =3D '.'=0D
+ file_lines[last_file] =3D []=0D
+=0D
+ for tmp_name in temp_file_dict:=0D
+ temp_file_dict[tmp_name][-1] =3D self.normalize_file_name(temp=
_file_dict[tmp_name][-1], True)=0D
+ if len(temp_file_dict[tmp_name]) > 1:=0D
+ temp_file_dict[tmp_name][-2] =3D self.normalize_file_name(=
temp_file_dict[tmp_name][-2], True)=0D
+=0D
+ for tmp_name in bsf_temp_dict:=0D
+ file =3D temp_file_dict[tmp_name][-1]=0D
+ if last_file !=3D file and len(temp_file_dict[tmp_name]) > 1:=
=0D
+ inc_file =3D temp_file_dict[tmp_name][-2]=0D
+ file_lines[inc_file].extend(['', '- !include %s' % temp_fi=
le_dict[tmp_name][-1], ''])=0D
+ last_file =3D file=0D
+ if file not in file_lines:=0D
+ file_lines[file] =3D []=0D
+ lines =3D file_lines[file]=0D
+ text =3D bsf_temp_dict[tmp_name]=0D
+ tmp_list =3D self.process_option_lines(text)=0D
+ self.template_fixup(tmp_name, tmp_list)=0D
+ template_dict[tmp_name] =3D tmp_list=0D
+ lines.append('%s: >' % tmp_name)=0D
+ lines.extend(self.output_dict(tmp_list, False)['.'])=0D
+ lines.append('\n')=0D
+ return file_lines=0D
+=0D
+ def output_config(self):=0D
+ """=0D
+ Output config block into a line list.=0D
+ """=0D
+ self.offset =3D 0=0D
+ self.base_offset =3D 0=0D
+ start, end =3D self.get_section_range('PcdsDynamicVpd.Upd')=0D
+ cfgs =3D self.process_option_lines(self.gen_cfg_data._DscLines[sta=
rt:end])=0D
+ self.config_fixup(cfgs)=0D
+ file_lines =3D self.output_dict(cfgs, True)=0D
+ return file_lines=0D
+=0D
+ def output_dict(self, cfgs, is_configs):=0D
+ """=0D
+ Output one config item into a line list.=0D
+ """=0D
+ file_lines =3D {}=0D
+ level =3D 0=0D
+ file =3D '.'=0D
+ for each in cfgs:=0D
+ if 'length' in each and int(each['length'], 0) =3D=3D 0:=0D
+ continue=0D
+=0D
+ if 'include' in each:=0D
+ if each['include']:=0D
+ each['include'] =3D self.normalize_file_name(each['inc=
lude'])=0D
+ file_lines[file].extend(['', '- !include %s' % each['i=
nclude'], ''])=0D
+ file =3D each['include']=0D
+ else:=0D
+ file =3D '.'=0D
+ continue=0D
+=0D
+ if file not in file_lines:=0D
+ file_lines[file] =3D []=0D
+=0D
+ lines =3D file_lines[file]=0D
+ name =3D each['cname']=0D
+=0D
+ prefix =3D name[0]=0D
+ if prefix =3D=3D '<':=0D
+ level +=3D 1=0D
+=0D
+ padding =3D ' ' * level=0D
+ if prefix not in '<>@':=0D
+ padding +=3D ' '=0D
+ else:=0D
+ name =3D name[1:]=0D
+ if prefix =3D=3D '@':=0D
+ padding +=3D ' '=0D
+=0D
+ if ':' in name:=0D
+ parts =3D name.split(':')=0D
+ name =3D parts[0]=0D
+=0D
+ padding =3D padding[2:] if is_configs else padding=0D
+=0D
+ if prefix !=3D '>':=0D
+ if 'expand' in each:=0D
+ lines.append('%s- %s' % (padding, each['expand']))=0D
+ else:=0D
+ lines.append('%s- %-12s :' % (padding, name))=0D
+=0D
+ for field in each:=0D
+ if field in ['cname', 'expand', 'include']:=0D
+ continue=0D
+ value_str =3D self.format_value(field, each[field], paddin=
g + ' ' * 16)=0D
+ full_line =3D ' %s %-12s : %s' % (padding, field, value_=
str)=0D
+ lines.extend(full_line.splitlines())=0D
+=0D
+ if prefix =3D=3D '>':=0D
+ level -=3D 1=0D
+ if level =3D=3D 0:=0D
+ lines.append('')=0D
+=0D
+ return file_lines=0D
+=0D
+=0D
+def bsf_to_dsc(bsf_file, dsc_file):=0D
+ fsp_dsc =3D CFspBsf2Dsc(bsf_file)=0D
+ dsc_lines =3D fsp_dsc.get_dsc_lines()=0D
+ fd =3D open(dsc_file, 'w')=0D
+ fd.write('\n'.join(dsc_lines))=0D
+ fd.close()=0D
+ return=0D
+=0D
+=0D
+def dsc_to_yaml(dsc_file, yaml_file):=0D
+ dsc2yaml =3D CFspDsc2Yaml()=0D
+ dsc2yaml.load_config_data_from_dsc(dsc_file)=0D
+=0D
+ cfgs =3D {}=0D
+ for cfg in ['Template', 'Option']:=0D
+ if cfg =3D=3D 'Template':=0D
+ file_lines =3D dsc2yaml.output_template()=0D
+ else:=0D
+ file_lines =3D dsc2yaml.output_config()=0D
+ for file in file_lines:=0D
+ lines =3D file_lines[file]=0D
+ if file =3D=3D '.':=0D
+ cfgs[cfg] =3D lines=0D
+ else:=0D
+ if('/' in file or '\\' in file):=0D
+ continue=0D
+ file =3D os.path.basename(file)=0D
+ fo =3D open(os.path.join(file), 'w')=0D
+ fo.write(__copyright_tmp__ % (cfg, date.today().year) + '\=
n\n')=0D
+ for line in lines:=0D
+ fo.write(line + '\n')=0D
+ fo.close()=0D
+=0D
+ variables =3D dsc2yaml.output_variable()=0D
+ fo =3D open(yaml_file, 'w')=0D
+ fo.write(__copyright_tmp__ % ('Default', date.today().year))=0D
+ if len(variables) > 0:=0D
+ fo.write('\n\nvariable:\n')=0D
+ for line in variables:=0D
+ fo.write(' ' + line + '\n')=0D
+=0D
+ fo.write('\n\ntemplate:\n')=0D
+ for line in cfgs['Template']:=0D
+ fo.write(' ' + line + '\n')=0D
+=0D
+ fo.write('\n\nconfigs:\n')=0D
+ for line in cfgs['Option']:=0D
+ fo.write(' ' + line + '\n')=0D
+=0D
+ fo.close()=0D
+=0D
+=0D
+def get_fsp_name_from_path(bsf_file):=0D
+ name =3D ''=0D
+ parts =3D bsf_file.split(os.sep)=0D
+ for part in parts:=0D
+ if part.endswith('FspBinPkg'):=0D
+ name =3D part[:-9]=0D
+ break=0D
+ if not name:=0D
+ raise Exception('Could not get FSP name from file path!')=0D
+ return name=0D
+=0D
+=0D
+def usage():=0D
+ print('\n'.join([=0D
+ "FspDscBsf2Yaml Version 0.10",=0D
+ "Usage:",=0D
+ " FspDscBsf2Yaml BsfFile|DscFile YamlFile"=0D
+ ]))=0D
+=0D
+=0D
+def main():=0D
+ #=0D
+ # Parse the options and args=0D
+ #=0D
+ argc =3D len(sys.argv)=0D
+ if argc < 3:=0D
+ usage()=0D
+ return 1=0D
+=0D
+ bsf_file =3D sys.argv[1]=0D
+ yaml_file =3D sys.argv[2]=0D
+ if os.path.isdir(yaml_file):=0D
+ yaml_file =3D os.path.join(yaml_file, get_fsp_name_from_path(bsf_f=
ile) + '.yaml')=0D
+=0D
+ if bsf_file.endswith('.dsc'):=0D
+ dsc_file =3D bsf_file=0D
+ bsf_file =3D ''=0D
+ else:=0D
+ dsc_file =3D os.path.splitext(yaml_file)[0] + '.dsc'=0D
+ bsf_to_dsc(bsf_file, dsc_file)=0D
+=0D
+ dsc_to_yaml(dsc_file, yaml_file)=0D
+=0D
+ print("'%s' was created successfully!" % yaml_file)=0D
+=0D
+ return 0=0D
+=0D
+=0D
+if __name__ =3D=3D '__main__':=0D
+ sys.exit(main())=0D
diff --git a/IntelFsp2Pkg/Tools/GenCfgOpt.py b/IntelFsp2Pkg/Tools/GenCfgOpt=
.py
index a0b8bba81e..660824b740 100644
--- a/IntelFsp2Pkg/Tools/GenCfgOpt.py
+++ b/IntelFsp2Pkg/Tools/GenCfgOpt.py
@@ -1,6 +1,6 @@
## @ GenCfgOpt.py=0D
#=0D
-# Copyright (c) 2014 - 2020, Intel Corporation. All rights reserved.<BR>=0D
+# Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.<BR>=0D
# SPDX-License-Identifier: BSD-2-Clause-Patent=0D
#=0D
##=0D
@@ -283,10 +283,10 @@ class CLogicalExpression:
return Result=0D
=0D
class CGenCfgOpt:=0D
- def __init__(self):=0D
+ def __init__(self, Mode =3D ''):=0D
self.Debug =3D False=0D
self.Error =3D ''=0D
-=0D
+ self.Mode =3D Mode=0D
self._GlobalDataDef =3D """=0D
GlobalDataDef=0D
SKUID =3D 0, "DEFAULT"=0D
@@ -300,18 +300,20 @@ List &EN_DIS
EndList=0D
=0D
"""=0D
-=0D
- self._BsfKeyList =3D ['FIND','NAME','HELP','TYPE','PAGE','OPTIO=
N','ORDER']=0D
+ self._BsfKeyList =3D ['FIND','NAME','HELP','TYPE','PAGE', 'PAGE=
S', 'BLOCK', 'OPTION','CONDITION','ORDER', 'MARKER', 'SUBT']=0D
self._HdrKeyList =3D ['HEADER','STRUCT', 'EMBED', 'COMMENT']=0D
self._BuidinOption =3D {'$EN_DIS' : 'EN_DIS'}=0D
=0D
self._MacroDict =3D {}=0D
+ self._VarDict =3D {}=0D
self._PcdsDict =3D {}=0D
self._CfgBlkDict =3D {}=0D
self._CfgPageDict =3D {}=0D
+ self._BsfTempDict =3D {}=0D
self._CfgItemList =3D []=0D
+ self._DscLines =3D []=0D
self._DscFile =3D ''=0D
- self._FvDir =3D ''=0D
+=0D
self._MapVer =3D 0=0D
self._DscTime =3D 0=0D
=0D
@@ -351,7 +353,7 @@ EndList
print ("INFO : Eval Ifdef [%s] : %s" % (Macro, Result))=0D
return Result=0D
=0D
- def ExpandMacros (self, Input):=0D
+ def ExpandMacros (self, Input, Preserve =3D False):=0D
Line =3D Input=0D
Match =3D re.findall("\$\(\w+\)", Input)=0D
if Match:=0D
@@ -362,7 +364,8 @@ EndList
else:=0D
if self.Debug:=0D
print ("WARN : %s is not defined" % Each)=0D
- Line =3D Line.replace(Each, Each[2:-1])=0D
+ if not Preserve:=0D
+ Line =3D Line.replace(Each, Each[2:-1])=0D
return Line=0D
=0D
def ExpandPcds (self, Input):=0D
@@ -386,6 +389,70 @@ EndList
print ("INFO : Eval Express [%s] : %s" % (Expr, Result))=0D
return Result=0D
=0D
+ def ValueToByteArray (self, ValueStr, Length):=0D
+ Match =3D re.match("\{\s*FILE:(.+)\}", ValueStr)=0D
+ if Match:=0D
+ FileList =3D Match.group(1).split(',')=0D
+ Result =3D bytearray()=0D
+ for File in FileList:=0D
+ File =3D File.strip()=0D
+ BinPath =3D os.path.join(os.path.dirname(self._DscFile), File)=
=0D
+ Result.extend(bytearray(open(BinPath, 'rb').read()))=0D
+ else:=0D
+ try:=0D
+ Result =3D bytearray(self.ValueToList(ValueStr, Length))=
=0D
+ except ValueError as e:=0D
+ raise Exception ("Bytes in '%s' must be in range 0~255 !" =
% ValueStr)=0D
+ if len(Result) < Length:=0D
+ Result.extend(b'\x00' * (Length - len(Result)))=0D
+ elif len(Result) > Length:=0D
+ raise Exception ("Value '%s' is too big to fit into %d bytes !=
" % (ValueStr, Length))=0D
+=0D
+ return Result[:Length]=0D
+=0D
+ def ValueToList (self, ValueStr, Length):=0D
+ if ValueStr[0] =3D=3D '{':=0D
+ Result =3D []=0D
+ BinList =3D ValueStr[1:-1].split(',')=0D
+ InBitField =3D False=0D
+ LastInBitField =3D False=0D
+ Value =3D 0=0D
+ BitLen =3D 0=0D
+ for Element in BinList:=0D
+ InBitField =3D False=0D
+ Each =3D Element.strip()=0D
+ if len(Each) =3D=3D 0:=0D
+ pass=0D
+ else:=0D
+ if Each[0] in ['"', "'"]:=0D
+ Result.extend(list(bytearray(Each[1:-1], 'utf-8'))=
)=0D
+ elif ':' in Each:=0D
+ Match =3D re.match("(.+):(\d+)b", Each)=0D
+ if Match is None:=0D
+ raise Exception("Invald value list format '%s'=
!" % Each)=0D
+ InBitField =3D True=0D
+ CurrentBitLen =3D int(Match.group(2))=0D
+ CurrentValue =3D ((self.EvaluateExpress(Match.gro=
up(1)) & (1<<CurrentBitLen) - 1)) << BitLen=0D
+ else:=0D
+ Result.append(self.EvaluateExpress(Each.strip()))=
=0D
+ if InBitField:=0D
+ Value +=3D CurrentValue=0D
+ BitLen +=3D CurrentBitLen=0D
+ if LastInBitField and ((not InBitField) or (Element =3D=3D=
BinList[-1])):=0D
+ if BitLen % 8 !=3D 0:=0D
+ raise Exception("Invald bit field length!")=0D
+ Result.extend(Val2Bytes(Value, BitLen // 8))=0D
+ Value =3D 0=0D
+ BitLen =3D 0=0D
+ LastInBitField =3D InBitField=0D
+ elif ValueStr.startswith("'") and ValueStr.endswith("'"):=0D
+ Result =3D Str2Bytes (ValueStr, Length)=0D
+ elif ValueStr.startswith('"') and ValueStr.endswith('"'):=0D
+ Result =3D Str2Bytes (ValueStr, Length)=0D
+ else:=0D
+ Result =3D Val2Bytes (self.EvaluateExpress(ValueStr), Length)=
=0D
+ return Result=0D
+=0D
def FormatListValue(self, ConfigDict):=0D
Struct =3D ConfigDict['struct']=0D
if Struct not in ['UINT8','UINT16','UINT32','UINT64']:=0D
@@ -424,28 +491,53 @@ EndList
self._DscFile =3D DscFile=0D
self._FvDir =3D FvDir=0D
=0D
+ self._DscLines =3D []=0D
+ self._BsfTempDict =3D {}=0D
+=0D
# Initial DSC time is parent DSC time.=0D
self._DscTime =3D os.path.getmtime(DscFile)=0D
=0D
+ CfgDict =3D {}=0D
+=0D
IsDefSect =3D False=0D
IsPcdSect =3D False=0D
IsUpdSect =3D False=0D
IsVpdSect =3D False=0D
+ IsTmpSect =3D False=0D
+=0D
+ TemplateName =3D ''=0D
=0D
IfStack =3D []=0D
ElifStack =3D []=0D
Error =3D 0=0D
ConfigDict =3D {}=0D
=0D
- DscFd =3D open(DscFile, "r")=0D
- DscLines =3D DscFd.readlines()=0D
- DscFd.close()=0D
+=0D
+ if type(DscFile) is list:=0D
+ # it is DSC lines already=0D
+ DscLines =3D DscFile=0D
+ self._DscFile =3D '.'=0D
+ else:=0D
+ DscFd =3D open(DscFile, "r")=0D
+ DscLines =3D DscFd.readlines()=0D
+ DscFd.close()=0D
+ self._DscFile =3D DscFile=0D
+=0D
+ SkipLines =3D 0=0D
=0D
MaxAlign =3D 32 #Default align to 32, but if there are 64 bit un=
it, align to 64=0D
SizeAlign =3D 0 #record the struct max align=0D
Base =3D 0 #Starting offset of sub-structure.=0D
+=0D
while len(DscLines):=0D
DscLine =3D DscLines.pop(0).strip()=0D
+ if SkipLines =3D=3D 0:=0D
+ self._DscLines.append (DscLine)=0D
+ else:=0D
+ SkipLines =3D SkipLines - 1=0D
+ if len(DscLine) =3D=3D 0:=0D
+ continue=0D
+=0D
Handle =3D False=0D
Match =3D re.match("^\[(.+)\]", DscLine)=0D
if Match is not None:=0D
@@ -453,11 +545,15 @@ EndList
IsPcdSect =3D False=0D
IsVpdSect =3D False=0D
IsUpdSect =3D False=0D
- if Match.group(1).lower() =3D=3D "Defines".lower():=0D
+ IsTmpSect =3D False=0D
+ SectionName =3D Match.group(1).lower()=0D
+ if SectionName =3D=3D "Defines".lower():=0D
IsDefSect =3D True=0D
- if (Match.group(1).lower() =3D=3D "PcdsFeatureFlag".lower=
() or Match.group(1).lower() =3D=3D "PcdsFixedAtBuild".lower()):=0D
+ if (SectionName =3D=3D "PcdsFeatureFlag".lower() or Secti=
onName =3D=3D "PcdsFixedAtBuild".lower()):=0D
IsPcdSect =3D True=0D
- elif Match.group(1).lower() =3D=3D "PcdsDynamicVpd.Upd".lo=
wer():=0D
+ elif SectionName =3D=3D "PcdsDynamicVpd.Tmp".lower():=0D
+ IsTmpSect =3D True=0D
+ elif SectionName =3D=3D "PcdsDynamicVpd.Upd".lower():=0D
ConfigDict =3D {}=0D
ConfigDict['header'] =3D 'ON'=0D
ConfigDict['region'] =3D 'UPD'=0D
@@ -465,90 +561,98 @@ EndList
ConfigDict['page'] =3D ''=0D
ConfigDict['name'] =3D ''=0D
ConfigDict['find'] =3D ''=0D
+ ConfigDict['marker'] =3D ''=0D
ConfigDict['struct'] =3D ''=0D
ConfigDict['embed'] =3D ''=0D
ConfigDict['comment'] =3D ''=0D
ConfigDict['subreg'] =3D []=0D
+ ConfigDict['condition'] =3D ''=0D
+ ConfigDict['option'] =3D ''=0D
IsUpdSect =3D True=0D
Offset =3D 0=0D
else:=0D
- if IsDefSect or IsPcdSect or IsUpdSect or IsVpdSect:=0D
- if re.match("^!else($|\s+#.+)", DscLine):=0D
+ if IsDefSect or IsPcdSect or IsUpdSect or IsVpdSect or IsT=
mpSect:=0D
+=0D
+ Match =3D False if DscLine[0] !=3D '!' else True=0D
+ if Match:=0D
+ Match =3D re.match("^!(else|endif|ifdef|ifndef|if|=
elseif|include)\s*(.+)?$", DscLine.split("#")[0])=0D
+ Keyword =3D Match.group(1) if Match else ''=0D
+ Remaining =3D Match.group(2) if Match else ''=0D
+ Remaining =3D '' if Remaining is None else Remaining.s=
trip()=0D
+=0D
+ if Keyword in ['if', 'elseif', 'ifdef', 'ifndef', 'inc=
lude'] and not Remaining:=0D
+ raise Exception ("ERROR: Expression is expected af=
ter '!if' or !elseif' for line '%s'" % DscLine)=0D
+=0D
+ if Keyword =3D=3D 'else':=0D
if IfStack:=0D
IfStack[-1] =3D not IfStack[-1]=0D
else:=0D
- print("ERROR: No paired '!if' found for '!else=
' for line '%s'" % DscLine)=0D
- raise SystemExit=0D
- elif re.match("^!endif($|\s+#.+)", DscLine):=0D
+ raise Exception ("ERROR: No paired '!if' found=
for '!else' for line '%s'" % DscLine)=0D
+ elif Keyword =3D=3D 'endif':=0D
if IfStack:=0D
IfStack.pop()=0D
Level =3D ElifStack.pop()=0D
if Level > 0:=0D
del IfStack[-Level:]=0D
else:=0D
- print("ERROR: No paired '!if' found for '!endi=
f' for line '%s'" % DscLine)=0D
- raise SystemExit=0D
- else:=0D
- Result =3D False=0D
- Match =3D re.match("!(ifdef|ifndef)\s+(.+)", DscLi=
ne)=0D
- if Match:=0D
- Result =3D self.EvaulateIfdef (Match.group(2))=
=0D
- if Match.group(1) =3D=3D 'ifndef':=0D
- Result =3D not Result=0D
- IfStack.append(Result)=0D
+ raise Exception ("ERROR: No paired '!if' found=
for '!endif' for line '%s'" % DscLine)=0D
+ elif Keyword =3D=3D 'ifdef' or Keyword =3D=3D 'ifndef'=
:=0D
+ Result =3D self.EvaulateIfdef (Remaining)=0D
+ if Keyword =3D=3D 'ifndef':=0D
+ Result =3D not Result=0D
+ IfStack.append(Result)=0D
+ ElifStack.append(0)=0D
+ elif Keyword =3D=3D 'if' or Keyword =3D=3D 'elseif':=0D
+ Result =3D self.EvaluateExpress(Remaining)=0D
+ if Keyword =3D=3D "if":=0D
ElifStack.append(0)=0D
+ IfStack.append(Result)=0D
+ else: #elseif=0D
+ if IfStack:=0D
+ IfStack[-1] =3D not IfStack[-1]=0D
+ IfStack.append(Result)=0D
+ ElifStack[-1] =3D ElifStack[-1] + 1=0D
+ else:=0D
+ raise Exception ("ERROR: No paired '!if' f=
ound for '!elif' for line '%s'" % DscLine)=0D
+ else:=0D
+ if IfStack:=0D
+ Handle =3D reduce(lambda x,y: x and y, IfStack=
)=0D
else:=0D
- Match =3D re.match("!(if|elseif)\s+(.+)", Dsc=
Line.split("#")[0])=0D
+ Handle =3D True=0D
+ if Handle:=0D
+ Match =3D re.match("!include\s+(.+)", DscLine)=
=0D
if Match:=0D
- Result =3D self.EvaluateExpress(Match.grou=
p(2))=0D
- if Match.group(1) =3D=3D "if":=0D
- ElifStack.append(0)=0D
- IfStack.append(Result)=0D
- else: #elseif=0D
- if IfStack:=0D
- IfStack[-1] =3D not IfStack[-1]=0D
- IfStack.append(Result)=0D
- ElifStack[-1] =3D ElifStack[-1] + =
1=0D
- else:=0D
- print("ERROR: No paired '!if' foun=
d for '!elif' for line '%s'" % DscLine)=0D
- raise SystemExit=0D
- else:=0D
- if IfStack:=0D
- Handle =3D reduce(lambda x,y: x and y,=
IfStack)=0D
+ IncludeFilePath =3D Match.group(1)=0D
+ IncludeFilePath =3D self.ExpandMacros(Incl=
udeFilePath)=0D
+ PackagesPath =3D os.getenv("PACKAGES_PATH"=
)=0D
+ if PackagesPath:=0D
+ for PackagePath in PackagesPath.split(os=
.pathsep):=0D
+ IncludeFilePathAbs =3D os.path.join(=
os.path.normpath(PackagePath), os.path.normpath(IncludeFilePath))=0D
+ if os.path.exists(IncludeFilePathAbs=
):=0D
+ IncludeDsc =3D open(IncludeFile=
PathAbs, "r")=0D
+ break=0D
else:=0D
- Handle =3D True=0D
- if Handle:=0D
- Match =3D re.match("!include\s+(.+)", =
DscLine)=0D
- if Match:=0D
- IncludeFilePath =3D Match.group(1)=
=0D
- IncludeFilePath =3D self.ExpandMac=
ros(IncludeFilePath)=0D
- PackagesPath =3D os.getenv("PACKAG=
ES_PATH")=0D
- if PackagesPath:=0D
- for PackagePath in PackagesPath.=
split(os.pathsep):=0D
- IncludeFilePathAbs =3D os.pa=
th.join(os.path.normpath(PackagePath), os.path.normpath(IncludeFilePath))=0D
- if os.path.exists(IncludeFil=
ePathAbs):=0D
- IncludeDsc =3D open(Inc=
ludeFilePathAbs, "r")=0D
- break=0D
- else:=0D
- IncludeDsc =3D open(IncludeFile=
Path, "r")=0D
- if IncludeDsc =3D=3D None:=0D
- print("ERROR: Cannot open file=
'%s'" % IncludeFilePath)=0D
- raise SystemExit=0D
-=0D
- # Update DscTime when newer DSC ti=
me found.=0D
- CurrentDscTime =3D os.path.getmtim=
e(os.path.realpath(IncludeDsc.name))=0D
- if CurrentDscTime > self._DscTime:=
=0D
- self._DscTime =3D CurrentDscTi=
me=0D
-=0D
- NewDscLines =3D IncludeDsc.readlin=
es()=0D
- IncludeDsc.close()=0D
- DscLines =3D NewDscLines + DscLine=
s=0D
- Offset =3D 0=0D
- else:=0D
- if DscLine.startswith('!'):=0D
- print("ERROR: Unrecognized dir=
ective for line '%s'" % DscLine)=0D
- raise SystemExit=0D
+ IncludeDsc =3D open(IncludeFilePath, "r=
")=0D
+ if IncludeDsc =3D=3D None:=0D
+ print("ERROR: Cannot open file '%s'" %=
IncludeFilePath)=0D
+ raise SystemExit=0D
+=0D
+ # Update DscTime when newer DSC time found=
.=0D
+ CurrentDscTime =3D os.path.getmtime(os.pat=
h.realpath(IncludeDsc.name))=0D
+ if CurrentDscTime > self._DscTime:=0D
+ self._DscTime =3D CurrentDscTime=0D
+=0D
+ NewDscLines =3D IncludeDsc.readlines()=0D
+ IncludeDsc.close()=0D
+ DscLines =3D NewDscLines + DscLines=0D
+ del self._DscLines[-1]=0D
+ Offset =3D 0=0D
+ else:=0D
+ if DscLine.startswith('!'):=0D
+ print("ERROR: Unrecognized directive f=
or line '%s'" % DscLine)=0D
+ raise SystemExit=0D
if not Handle:=0D
+ del self._DscLines[-1]=0D
continue=0D
=0D
if IsDefSect:=0D
@@ -556,7 +660,7 @@ EndList
#DEFINE FSP_T_UPD_TOOL_GUID =3D 34686CA3-34F9-4901-B82A-BA=
630F0714C6=0D
#DEFINE FSP_M_UPD_TOOL_GUID =3D 39A250DB-E465-4DD1-A2AC-E2=
BD3C0E2385=0D
#DEFINE FSP_S_UPD_TOOL_GUID =3D CAE3605B-5B34-4C85-B3D7-27=
D54273C40F=0D
- Match =3D re.match("^\s*(?:DEFINE\s+)*(\w+)\s*=3D\s*([/$()=
-.\w]+)", DscLine)=0D
+ Match =3D re.match("^\s*(?:DEFINE\s+)*(\w+)\s*=3D\s*(.+)",=
DscLine)=0D
if Match:=0D
self._MacroDict[Match.group(1)] =3D self.ExpandMacros(=
Match.group(2))=0D
if self.Debug:=0D
@@ -575,6 +679,23 @@ EndList
if Match:=0D
self._PcdsDict[Match.group(1)] =3D Match.group=
(2)=0D
i +=3D 1=0D
+=0D
+ elif IsTmpSect:=0D
+ # !BSF DEFT:{GPIO_TMPL:START}=0D
+ Match =3D re.match("^\s*#\s+(!BSF)\s+DEFT:{(.+?):(START|EN=
D)}", DscLine)=0D
+ if Match:=0D
+ if Match.group(3) =3D=3D 'START' and not TemplateName:=
=0D
+ TemplateName =3D Match.group(2).strip()=0D
+ self._BsfTempDict[TemplateName] =3D []=0D
+ if Match.group(3) =3D=3D 'END' and (TemplateName =3D=
=3D Match.group(2).strip()) and TemplateName:=0D
+ TemplateName =3D ''=0D
+ else:=0D
+ if TemplateName:=0D
+ Match =3D re.match("^!include\s*(.+)?$", DscLine)=
=0D
+ if Match:=0D
+ continue=0D
+ self._BsfTempDict[TemplateName].append(DscLine)=0D
+=0D
else:=0D
Match =3D re.match("^\s*#\s+(!BSF|@Bsf|!HDR)\s+(.+)", DscL=
ine)=0D
if Match:=0D
@@ -630,9 +751,9 @@ EndList
Match =3D re.match("^\s*#\s*@ValidRange\s*(.+)\s*\|\s*(.+)=
\s*-\s*(.+)\s*", DscLine)=0D
if Match:=0D
if "0x" in Match.group(2) or "0x" in Match.group(3):=0D
- ConfigDict['type'] =3D "EditNum, HEX, (%s,%s)" % (M=
atch.group(2), Match.group(3))=0D
+ ConfigDict['type'] =3D "EditNum, HEX, (%s,%s)" % (=
Match.group(2), Match.group(3))=0D
else:=0D
- ConfigDict['type'] =3D "EditNum, DEC, (%s,%s)" % (M=
atch.group(2), Match.group(3))=0D
+ ConfigDict['type'] =3D "EditNum, DEC, (%s,%s)" % (=
Match.group(2), Match.group(3))=0D
=0D
Match =3D re.match("^\s*##\s+(.+)", DscLine)=0D
if Match:=0D
@@ -748,6 +869,7 @@ EndList
ConfigDict['struct'] =3D ''=0D
ConfigDict['embed'] =3D ''=0D
ConfigDict['comment'] =3D ''=0D
+ ConfigDict['marker'] =3D ''=0D
ConfigDict['order'] =3D -1=0D
ConfigDict['subreg'] =3D []=0D
ConfigDict['option'] =3D ''=0D
@@ -786,9 +908,8 @@ EndList
bitsvalue =3D bitsvalue[::-1]=0D
bitslen =3D len(bitsvalue)=0D
if start > bitslen or end > bitslen:=0D
- print ("Invalid bits offset [%d,%d] for %s" % (start, end, sub=
item['name']))=0D
- raise SystemExit=0D
- return hex(int(bitsvalue[start:end][::-1], 2))=0D
+ raise Exception ("Invalid bits offset [%d,%d] %d for %s" % (st=
art, end, bitslen, subitem['name']))=0D
+ return '0x%X' % (int(bitsvalue[start:end][::-1], 2))=0D
=0D
def UpdateSubRegionDefaultValue (self):=0D
Error =3D 0=0D
@@ -888,63 +1009,142 @@ EndList
TxtFd.close()=0D
return 0=0D
=0D
- def ProcessMultilines (self, String, MaxCharLength):=0D
- Multilines =3D ''=0D
- StringLength =3D len(String)=0D
- CurrentStringStart =3D 0=0D
- StringOffset =3D 0=0D
- BreakLineDict =3D []=0D
- if len(String) <=3D MaxCharLength:=0D
- while (StringOffset < StringLength):=0D
- if StringOffset >=3D 1:=0D
- if String[StringOffset - 1] =3D=3D '\\' and String=
[StringOffset] =3D=3D 'n':=0D
- BreakLineDict.append (StringOffset + 1)=0D
- StringOffset +=3D 1=0D
- if BreakLineDict !=3D []:=0D
- for Each in BreakLineDict:=0D
- Multilines +=3D " %s\n" % String[CurrentStringSta=
rt:Each].lstrip()=0D
- CurrentStringStart =3D Each=0D
- if StringLength - CurrentStringStart > 0:=0D
- Multilines +=3D " %s\n" % String[CurrentStringSta=
rt:].lstrip()=0D
+ def CreateVarDict (self):=0D
+ Error =3D 0=0D
+ self._VarDict =3D {}=0D
+ if len(self._CfgItemList) > 0:=0D
+ Item =3D self._CfgItemList[-1]=0D
+ self._VarDict['_LENGTH_'] =3D '%d' % (Item['offset'] + Item['l=
ength'])=0D
+ for Item in self._CfgItemList:=0D
+ Embed =3D Item['embed']=0D
+ Match =3D re.match("^(\w+):(\w+):(START|END)", Embed)=0D
+ if Match:=0D
+ StructName =3D Match.group(1)=0D
+ VarName =3D '_%s_%s_' % (Match.group(3), StructName)=0D
+ if Match.group(3) =3D=3D 'END':=0D
+ self._VarDict[VarName] =3D Item['offset'] + Item['leng=
th']=0D
+ self._VarDict['_LENGTH_%s_' % StructName] =3D \=0D
+ self._VarDict['_END_%s_' % StructName] - self._Var=
Dict['_START_%s_' % StructName]=0D
+ if Match.group(2).startswith('TAG_'):=0D
+ if (self.Mode !=3D 'FSP') and (self._VarDict['_LEN=
GTH_%s_' % StructName] % 4):=0D
+ raise Exception("Size of structure '%s' is %d,=
not DWORD aligned !" % (StructName, self._VarDict['_LENGTH_%s_' % StructNa=
me]))=0D
+ self._VarDict['_TAG_%s_' % StructName] =3D int (Ma=
tch.group(2)[4:], 16) & 0xFFF=0D
else:=0D
- Multilines =3D " %s\n" % String=0D
+ self._VarDict[VarName] =3D Item['offset']=0D
+ if Item['marker']:=0D
+ self._VarDict['_OFFSET_%s_' % Item['marker'].strip()] =3D =
Item['offset']=0D
+ return Error=0D
+=0D
+ def UpdateBsfBitUnit (self, Item):=0D
+ BitTotal =3D 0=0D
+ BitOffset =3D 0=0D
+ StartIdx =3D 0=0D
+ Unit =3D None=0D
+ UnitDec =3D {1:'BYTE', 2:'WORD', 4:'DWORD', 8:'QWORD'}=0D
+ for Idx, SubItem in enumerate(Item['subreg']):=0D
+ if Unit is None:=0D
+ Unit =3D SubItem['bitunit']=0D
+ BitLength =3D SubItem['bitlength']=0D
+ BitTotal +=3D BitLength=0D
+ BitOffset +=3D BitLength=0D
+=0D
+ if BitOffset > 64 or BitOffset > Unit * 8:=0D
+ break=0D
+=0D
+ if BitOffset =3D=3D Unit * 8:=0D
+ for SubIdx in range (StartIdx, Idx + 1):=0D
+ Item['subreg'][SubIdx]['bitunit'] =3D Unit=0D
+ BitOffset =3D 0=0D
+ StartIdx =3D Idx + 1=0D
+ Unit =3D None=0D
+=0D
+ if BitOffset > 0:=0D
+ raise Exception ("Bit fields cannot fit into %s for '%s.%s' !"=
% (UnitDec[Unit], Item['cname'], SubItem['cname']))=0D
+=0D
+ ExpectedTotal =3D Item['length'] * 8=0D
+ if Item['length'] * 8 !=3D BitTotal:=0D
+ raise Exception ("Bit fields total length (%d) does not match =
length (%d) of '%s' !" % (BitTotal, ExpectedTotal, Item['cname']))=0D
+=0D
+ def UpdateDefaultValue (self):=0D
+ Error =3D 0=0D
+ for Idx, Item in enumerate(self._CfgItemList):=0D
+ if len(Item['subreg']) =3D=3D 0:=0D
+ Value =3D Item['value']=0D
+ if (len(Value) > 0) and (Value[0] =3D=3D '{' or Value[0] =
=3D=3D "'" or Value[0] =3D=3D '"'):=0D
+ # {XXX} or 'XXX' strings=0D
+ self.FormatListValue(self._CfgItemList[Idx])=0D
+ else:=0D
+ Match =3D re.match("(0x[0-9a-fA-F]+|[0-9]+)", Value)=0D
+ if not Match:=0D
+ NumValue =3D self.EvaluateExpress (Value)=0D
+ Item['value'] =3D '0x%X' % NumValue=0D
else:=0D
- NewLineStart =3D 0=0D
- NewLineCount =3D 0=0D
- FoundSpaceChar =3D False=0D
- while (StringOffset < StringLength):=0D
- if StringOffset >=3D 1:=0D
- if NewLineCount >=3D MaxCharLength - 1:=0D
- if String[StringOffset] =3D=3D ' ' and StringL=
ength - StringOffset > 10:=0D
- BreakLineDict.append (NewLineStart + NewLi=
neCount)=0D
- NewLineStart =3D NewLineStart + NewLineCou=
nt=0D
- NewLineCount =3D 0=0D
- FoundSpaceChar =3D True=0D
- elif StringOffset =3D=3D StringLength - 1 and =
FoundSpaceChar =3D=3D False:=0D
- BreakLineDict.append (0)=0D
- if String[StringOffset - 1] =3D=3D '\\' and String=
[StringOffset] =3D=3D 'n':=0D
- BreakLineDict.append (StringOffset + 1)=0D
- NewLineStart =3D StringOffset + 1=0D
+ ValArray =3D self.ValueToByteArray (Item['value'], Item['l=
ength'])=0D
+ for SubItem in Item['subreg']:=0D
+ SubItem['value'] =3D self.GetBsfBitFields(SubItem, V=
alArray)=0D
+ self.UpdateBsfBitUnit (Item)=0D
+ return Error=0D
+=0D
+ def ProcessMultilines (self, String, MaxCharLength):=0D
+ Multilines =3D ''=0D
+ StringLength =3D len(String)=0D
+ CurrentStringStart =3D 0=0D
+ StringOffset =3D 0=0D
+ BreakLineDict =3D []=0D
+ if len(String) <=3D MaxCharLength:=0D
+ while (StringOffset < StringLength):=0D
+ if StringOffset >=3D 1:=0D
+ if String[StringOffset - 1] =3D=3D '\\' and String[Str=
ingOffset] =3D=3D 'n':=0D
+ BreakLineDict.append (StringOffset + 1)=0D
+ StringOffset +=3D 1=0D
+ if BreakLineDict !=3D []:=0D
+ for Each in BreakLineDict:=0D
+ Multilines +=3D " %s\n" % String[CurrentStringStart:E=
ach].lstrip()=0D
+ CurrentStringStart =3D Each=0D
+ if StringLength - CurrentStringStart > 0:=0D
+ Multilines +=3D " %s\n" % String[CurrentStringStart:]=
.lstrip()=0D
+ else:=0D
+ Multilines =3D " %s\n" % String=0D
+ else:=0D
+ NewLineStart =3D 0=0D
+ NewLineCount =3D 0=0D
+ FoundSpaceChar =3D False=0D
+ while (StringOffset < StringLength):=0D
+ if StringOffset >=3D 1:=0D
+ if NewLineCount >=3D MaxCharLength - 1:=0D
+ if String[StringOffset] =3D=3D ' ' and StringLengt=
h - StringOffset > 10:=0D
+ BreakLineDict.append (NewLineStart + NewLineCo=
unt)=0D
+ NewLineStart =3D NewLineStart + NewLineCount=0D
NewLineCount =3D 0=0D
- StringOffset +=3D 1=0D
- NewLineCount +=3D 1=0D
- if BreakLineDict !=3D []:=0D
- BreakLineDict.sort ()=0D
- for Each in BreakLineDict:=0D
- if Each > 0:=0D
- Multilines +=3D " %s\n" % String[CurrentStrin=
gStart:Each].lstrip()=0D
- CurrentStringStart =3D Each=0D
- if StringLength - CurrentStringStart > 0:=0D
- Multilines +=3D " %s\n" % String[CurrentStringSta=
rt:].lstrip()=0D
- return Multilines=0D
-=0D
- def CreateField (self, Item, Name, Length, Offset, Struct, BsfName, He=
lp, Option):=0D
+ FoundSpaceChar =3D True=0D
+ elif StringOffset =3D=3D StringLength - 1 and Foun=
dSpaceChar =3D=3D False:=0D
+ BreakLineDict.append (0)=0D
+ if String[StringOffset - 1] =3D=3D '\\' and String[Str=
ingOffset] =3D=3D 'n':=0D
+ BreakLineDict.append (StringOffset + 1)=0D
+ NewLineStart =3D StringOffset + 1=0D
+ NewLineCount =3D 0=0D
+ StringOffset +=3D 1=0D
+ NewLineCount +=3D 1=0D
+ if BreakLineDict !=3D []:=0D
+ BreakLineDict.sort ()=0D
+ for Each in BreakLineDict:=0D
+ if Each > 0:=0D
+ Multilines +=3D " %s\n" % String[CurrentStringSta=
rt:Each].lstrip()=0D
+ CurrentStringStart =3D Each=0D
+ if StringLength - CurrentStringStart > 0:=0D
+ Multilines +=3D " %s\n" % String[CurrentStringStart:]=
.lstrip()=0D
+ return Multilines=0D
+=0D
+ def CreateField (self, Item, Name, Length, Offset, Struct, BsfName, He=
lp, Option, BitsLength =3D None):=0D
PosName =3D 28=0D
PosComment =3D 30=0D
NameLine=3D''=0D
HelpLine=3D''=0D
OptionLine=3D''=0D
=0D
+ if Length =3D=3D 0 and Name =3D=3D 'Dummy':=0D
+ return '\n'=0D
+=0D
IsArray =3D False=0D
if Length in [1,2,4,8]:=0D
Type =3D "UINT%d" % (Length * 8)=0D
@@ -992,7 +1192,12 @@ EndList
else:=0D
OffsetStr =3D '0x%04X' % Offset=0D
=0D
- return "\n/** Offset %s%s%s%s**/\n %s%s%s;\n" % (OffsetStr, NameL=
ine, HelpLine, OptionLine, Type, ' ' * Space1, Name,)=0D
+ if BitsLength is None:=0D
+ BitsLength =3D ''=0D
+ else:=0D
+ BitsLength =3D ' : %d' % BitsLength=0D
+=0D
+ return "\n/** Offset %s%s%s%s**/\n %s%s%s%s;\n" % (OffsetStr, Nam=
eLine, HelpLine, OptionLine, Type, ' ' * Space1, Name, BitsLength)=0D
=0D
def PostProcessBody (self, TextBody):=0D
NewTextBody =3D []=0D
@@ -1097,6 +1302,7 @@ EndList
UpdStructure =3D ['FSPT_UPD', 'FSPM_UPD', 'FSPS_UPD']=0D
for Item in self._CfgItemList:=0D
if Item["cname"] =3D=3D 'Signature' and Item["value"][0:6]=
in UpdSignature:=0D
+ Item["offset"] =3D 0 # re-initialize offset to 0 when =
new UPD structure starting=0D
UpdOffsetTable.append (Item["offset"])=0D
=0D
for UpdIdx in range(len(UpdOffsetTable)):=0D
diff --git a/IntelFsp2Pkg/Tools/Tests/ExpectedFspUpd.h b/IntelFsp2Pkg/Tools=
/Tests/ExpectedFspUpd.h
new file mode 100644
index 0000000000..be2ed8aa99
--- /dev/null
+++ b/IntelFsp2Pkg/Tools/Tests/ExpectedFspUpd.h
@@ -0,0 +1,16 @@
+#ifndef __FSPUPD_H__=0D
+#define __FSPUPD_H__=0D
+=0D
+#include <FspEas.h>=0D
+=0D
+#pragma pack(1)=0D
+=0D
+#define FSPT_UPD_SIGNATURE 0x545F4450554D4551 /* 'QEM=
UPD_T' */=0D
+=0D
+#define FSPM_UPD_SIGNATURE 0x4D5F4450554D4551 /* 'QEM=
UPD_M' */=0D
+=0D
+#define FSPS_UPD_SIGNATURE 0x535F4450554D4551 /* 'QEM=
UPD_S' */=0D
+=0D
+#pragma pack()=0D
+=0D
+#endif=0D
diff --git a/IntelFsp2Pkg/Tools/Tests/ExpectedFspmUpd.h b/IntelFsp2Pkg/Tool=
s/Tests/ExpectedFspmUpd.h
new file mode 100644
index 0000000000..83fd06ecb4
--- /dev/null
+++ b/IntelFsp2Pkg/Tools/Tests/ExpectedFspmUpd.h
@@ -0,0 +1,75 @@
+#ifndef __FSPMUPD_H__=0D
+#define __FSPMUPD_H__=0D
+=0D
+#include <FspUpd.h>=0D
+=0D
+#pragma pack(1)=0D
+=0D
+=0D
+/** Fsp M Configuration=0D
+**/=0D
+typedef struct {=0D
+=0D
+/** Offset 0x00C8 - Debug Serial Port Base address=0D
+ Debug serial port base address. This option will be used only when the '=
Serial Port=0D
+ Debug Device' option is set to 'External Device'. 0x00000000(Default).=0D
+**/=0D
+ UINT32 SerialDebugPortAddress;=0D
+=0D
+/** Offset 0x00CC - Debug Serial Port Type=0D
+ 16550 compatible debug serial port resource type. NONE means no serial p=
ort support.=0D
+ 0x02:MMIO(Default).=0D
+ 0:NONE, 1:I/O, 2:MMIO=0D
+**/=0D
+ UINT8 SerialDebugPortType;=0D
+=0D
+/** Offset 0x00CD - Serial Port Debug Device=0D
+ Select active serial port device for debug. For SOC UART devices,'Debug =
Serial Port=0D
+ Base' options will be ignored. 0x02:SOC UART2(Default).=0D
+ 0:SOC UART0, 1:SOC UART1, 2:SOC UART2, 3:External Device=0D
+**/=0D
+ UINT8 SerialDebugPortDevice;=0D
+=0D
+/** Offset 0x00CE - Debug Serial Port Stride Size=0D
+ Debug serial port register map stride size in bytes. 0x00:1, 0x02:4(Defa=
ult).=0D
+ 0:1, 2:4=0D
+**/=0D
+ UINT8 SerialDebugPortStrideSize;=0D
+=0D
+/** Offset 0x00CF=0D
+**/=0D
+ UINT8 UnusedUpdSpace2[1];=0D
+=0D
+/** Offset 0x00D0=0D
+**/=0D
+ UINT8 ReservedFspmUpd[4];=0D
+} FSP_M_CONFIG;=0D
+=0D
+/** Fsp M UPD Configuration=0D
+**/=0D
+typedef struct {=0D
+=0D
+/** Offset 0x0000=0D
+**/=0D
+ FSP_UPD_HEADER FspUpdHeader;=0D
+=0D
+/** Offset 0x00A8=0D
+**/=0D
+ FSPM_ARCH_UPD FspmArchUpd;=0D
+=0D
+/** Offset 0x00C8=0D
+**/=0D
+ FSP_M_CONFIG FspmConfig;=0D
+=0D
+/** Offset 0x00D4=0D
+**/=0D
+ UINT8 UnusedUpdSpace3[2];=0D
+=0D
+/** Offset 0x00D6=0D
+**/=0D
+ UINT16 UpdTerminator;=0D
+} FSPM_UPD;=0D
+=0D
+#pragma pack()=0D
+=0D
+#endif=0D
diff --git a/IntelFsp2Pkg/Tools/Tests/ExpectedFspsUpd.h b/IntelFsp2Pkg/Tool=
s/Tests/ExpectedFspsUpd.h
new file mode 100644
index 0000000000..e2bc54a61d
--- /dev/null
+++ b/IntelFsp2Pkg/Tools/Tests/ExpectedFspsUpd.h
@@ -0,0 +1,69 @@
+#ifndef __FSPSUPD_H__=0D
+#define __FSPSUPD_H__=0D
+=0D
+#include <FspUpd.h>=0D
+=0D
+#pragma pack(1)=0D
+=0D
+=0D
+/** Fsp S Configuration=0D
+**/=0D
+typedef struct {=0D
+=0D
+/** Offset 0x0118 - BMP Logo Data Size=0D
+ BMP logo data buffer size. 0x00000000(Default).=0D
+**/=0D
+ UINT32 LogoSize;=0D
+=0D
+/** Offset 0x011C - BMP Logo Data Pointer=0D
+ BMP logo data pointer to a BMP format buffer. 0x00000000(Default).=0D
+**/=0D
+ UINT32 LogoPtr;=0D
+=0D
+/** Offset 0x0120 - Graphics Configuration Data Pointer=0D
+ Graphics configuration data used for initialization. 0x00000000(Default)=
.=0D
+**/=0D
+ UINT32 GraphicsConfigPtr;=0D
+=0D
+/** Offset 0x0124 - PCI GFX Temporary MMIO Base=0D
+ PCI Temporary PCI GFX Base used before full PCI enumeration. 0x80000000(=
Default).=0D
+**/=0D
+ UINT32 PciTempResourceBase;=0D
+=0D
+/** Offset 0x0128=0D
+**/=0D
+ UINT8 UnusedUpdSpace1[3];=0D
+=0D
+/** Offset 0x012B=0D
+**/=0D
+ UINT8 ReservedFspsUpd;=0D
+} FSP_S_CONFIG;=0D
+=0D
+/** Fsp S UPD Configuration=0D
+**/=0D
+typedef struct {=0D
+=0D
+/** Offset 0x0000=0D
+**/=0D
+ FSP_UPD_HEADER FspUpdHeader;=0D
+=0D
+/** Offset 0x00F8=0D
+**/=0D
+ FSPS_ARCH_UPD FspsArchUpd;=0D
+=0D
+/** Offset 0x0118=0D
+**/=0D
+ FSP_S_CONFIG FspsConfig;=0D
+=0D
+/** Offset 0x012C=0D
+**/=0D
+ UINT8 UnusedUpdSpace2[2];=0D
+=0D
+/** Offset 0x012E=0D
+**/=0D
+ UINT16 UpdTerminator;=0D
+} FSPS_UPD;=0D
+=0D
+#pragma pack()=0D
+=0D
+#endif=0D
diff --git a/IntelFsp2Pkg/Tools/Tests/ExpectedFsptUpd.h b/IntelFsp2Pkg/Tool=
s/Tests/ExpectedFsptUpd.h
new file mode 100644
index 0000000000..25b8a7d63a
--- /dev/null
+++ b/IntelFsp2Pkg/Tools/Tests/ExpectedFsptUpd.h
@@ -0,0 +1,87 @@
+#ifndef __FSPTUPD_H__=0D
+#define __FSPTUPD_H__=0D
+=0D
+#include <FspUpd.h>=0D
+=0D
+#pragma pack(1)=0D
+=0D
+=0D
+/** Fsp T Common UPD=0D
+**/=0D
+typedef struct {=0D
+=0D
+/** Offset 0x0040=0D
+**/=0D
+ UINT8 Revision;=0D
+=0D
+/** Offset 0x0041=0D
+**/=0D
+ UINT8 Reserved[3];=0D
+=0D
+/** Offset 0x0044=0D
+**/=0D
+ UINT32 MicrocodeRegionBase;=0D
+=0D
+/** Offset 0x0048=0D
+**/=0D
+ UINT32 MicrocodeRegionLength;=0D
+=0D
+/** Offset 0x004C=0D
+**/=0D
+ UINT32 CodeRegionBase;=0D
+=0D
+/** Offset 0x0050=0D
+**/=0D
+ UINT32 CodeRegionLength;=0D
+=0D
+/** Offset 0x0054=0D
+**/=0D
+ UINT8 Reserved1[12];=0D
+} FSPT_COMMON_UPD;=0D
+=0D
+/** Fsp T Configuration=0D
+**/=0D
+typedef struct {=0D
+=0D
+/** Offset 0x0060 - Chicken bytes to test Hex config=0D
+ This option shows how to present option for 4 bytes data=0D
+**/=0D
+ UINT32 ChickenBytes;=0D
+=0D
+/** Offset 0x0064=0D
+**/=0D
+ UINT8 ReservedFsptUpd1[28];=0D
+} FSP_T_CONFIG;=0D
+=0D
+/** Fsp T UPD Configuration=0D
+**/=0D
+typedef struct {=0D
+=0D
+/** Offset 0x0000=0D
+**/=0D
+ FSP_UPD_HEADER FspUpdHeader;=0D
+=0D
+/** Offset 0x0020=0D
+**/=0D
+ FSPT_ARCH_UPD FsptArchUpd;=0D
+=0D
+/** Offset 0x0040=0D
+**/=0D
+ FSPT_COMMON_UPD FsptCommonUpd;=0D
+=0D
+/** Offset 0x0060=0D
+**/=0D
+ FSP_T_CONFIG FsptConfig;=0D
+=0D
+/** Offset 0x0080=0D
+**/=0D
+ UINT8 UnusedUpdSpace0[6];=0D
+=0D
+/** Offset 0x0086=0D
+**/=0D
+ UINT16 UpdTerminator;=0D
+} FSPT_UPD;=0D
+=0D
+#pragma pack()=0D
+=0D
+#endif=0D
diff --git a/IntelFsp2Pkg/Tools/Tests/ExpectedOutput.bsf b/IntelFsp2Pkg/Too=
ls/Tests/ExpectedOutput.bsf
new file mode 100644
index 0000000000..750e1b4faf
--- /dev/null
+++ b/IntelFsp2Pkg/Tools/Tests/ExpectedOutput.bsf
@@ -0,0 +1,88 @@
+GlobalDataDef=0D
+ SKUID =3D 0, "DEFAULT"=0D
+EndGlobalData=0D
+=0D
+=0D
+StructDef=0D
+=0D
+ Find "QEMUPD_T"=0D
+ $gQemuFspPkgTokenSpaceGuid_Revision 1 b=
ytes $_DEFAULT_ =3D 0x01=0D
+ Skip 87 bytes=0D
+ $gQemuFspPkgTokenSpaceGuid_ChickenBytes 4 b=
ytes $_DEFAULT_ =3D 0x00000000=0D
+=0D
+ Find "QEMUPD_M"=0D
+ $gQemuFspPkgTokenSpaceGuid_Revision 1 b=
ytes $_DEFAULT_ =3D 0x01=0D
+ Skip 35 bytes=0D
+ $gQemuFspPkgTokenSpaceGuid_StackBase 4 b=
ytes $_DEFAULT_ =3D 0x00070000=0D
+ $gQemuFspPkgTokenSpaceGuid_StackSize 4 b=
ytes $_DEFAULT_ =3D 0x00010000=0D
+ $gQemuFspPkgTokenSpaceGuid_BootLoaderTolumSize 4 b=
ytes $_DEFAULT_ =3D 0x00000000=0D
+ $gPlatformFspPkgTokenSpaceGuid_Bootmode 4 b=
ytes $_DEFAULT_ =3D 0x00000000=0D
+ Skip 8 bytes=0D
+ $gQemuFspPkgTokenSpaceGuid_SerialDebugPortAddress 4 b=
ytes $_DEFAULT_ =3D 0x00000000=0D
+ $gQemuFspPkgTokenSpaceGuid_SerialDebugPortType 1 b=
ytes $_DEFAULT_ =3D 0x02=0D
+ $gQemuFspPkgTokenSpaceGuid_SerialDebugPortDevice 1 b=
ytes $_DEFAULT_ =3D 0x02=0D
+ $gQemuFspPkgTokenSpaceGuid_SerialDebugPortStrideSize 1 b=
ytes $_DEFAULT_ =3D 0x02=0D
+=0D
+ Find "QEMUPD_S"=0D
+ $gQemuFspPkgTokenSpaceGuid_Revision 1 b=
ytes $_DEFAULT_ =3D 0x01=0D
+ Skip 55 bytes=0D
+ $gQemuFspPkgTokenSpaceGuid_LogoSize 4 b=
ytes $_DEFAULT_ =3D 0x00000000=0D
+ $gQemuFspPkgTokenSpaceGuid_LogoPtr 4 b=
ytes $_DEFAULT_ =3D 0x00000000=0D
+ $gQemuFspPkgTokenSpaceGuid_GraphicsConfigPtr 4 b=
ytes $_DEFAULT_ =3D 0x00000000=0D
+ $gQemuFspPkgTokenSpaceGuid_PciTempResourceBase 4 b=
ytes $_DEFAULT_ =3D 0x80000000=0D
+=0D
+EndStruct=0D
+=0D
+=0D
+List &EN_DIS=0D
+ Selection 0x1 , "Enabled"=0D
+ Selection 0x0 , "Disabled"=0D
+EndList=0D
+=0D
+List &gQemuFspPkgTokenSpaceGuid_SerialDebugPortType=0D
+ Selection 0 , "NONE"=0D
+ Selection 1 , "I/O"=0D
+ Selection 2 , "MMIO"=0D
+EndList=0D
+=0D
+List &gQemuFspPkgTokenSpaceGuid_SerialDebugPortDevice=0D
+ Selection 0 , "SOC UART0"=0D
+ Selection 1 , "SOC UART1"=0D
+ Selection 2 , "SOC UART2"=0D
+ Selection 3 , "External Device"=0D
+EndList=0D
+=0D
+List &gQemuFspPkgTokenSpaceGuid_SerialDebugPortStrideSize=0D
+ Selection 0 , "1"=0D
+ Selection 2 , "4"=0D
+EndList=0D
+=0D
+BeginInfoBlock=0D
+ PPVer "0.1"=0D
+ Description "QEMU Platform"=0D
+EndInfoBlock=0D
+=0D
+Page "FSP T"=0D
+ EditNum $gQemuFspPkgTokenSpaceGuid_ChickenBytes, "Chicken bytes to tes=
t Hex config", HEX,=0D
+ Help "This option shows how to present option for 4 bytes data"=0D
+ "Valid range: 0x00000000 ~ 0xFFFFFFFF"=0D
+EndPage=0D
+=0D
+Page "FSP MemoryInit Settings"=0D
+ EditNum $gQemuFspPkgTokenSpaceGuid_SerialDebugPortAddress, "Debug Seri=
al Port Base address", HEX,=0D
+ Help "Debug serial port base address. This option will be used onl=
y when the 'Serial Port Debug Device' option is set to 'External Device'. 0=
x00000000(Default)."=0D
+ "Valid range: 0x00000000 ~ 0xFFFFFFFF"=0D
+ Combo $gQemuFspPkgTokenSpaceGuid_SerialDebugPortType, "Debug Serial Po=
rt Type", &gQemuFspPkgTokenSpaceGuid_SerialDebugPortType,=0D
+ Help "16550 compatible debug serial port resource type. NONE means=
no serial port support. 0x02:MMIO(Default)."=0D
+ Combo $gQemuFspPkgTokenSpaceGuid_SerialDebugPortDevice, "Serial Port D=
ebug Device", &gQemuFspPkgTokenSpaceGuid_SerialDebugPortDevice,=0D
+ Help "Select active serial port device for debug. For SOC UART dev=
ices,'Debug Serial Port Base' options will be ignored. 0x02:SOC UART2(Defau=
lt)."=0D
+ Combo $gQemuFspPkgTokenSpaceGuid_SerialDebugPortStrideSize, "Debug Ser=
ial Port Stride Size", &gQemuFspPkgTokenSpaceGuid_SerialDebugPortStrideSize=
,=0D
+ Help "Debug serial port register map stride size in bytes. 0x00:1,=
0x02:4(Default)."=0D
+EndPage=0D
+=0D
+Page "FSP SiliconInit Settings"=0D
+ EditNum $gQemuFspPkgTokenSpaceGuid_PciTempResourceBase, "PCI GFX Tempo=
rary MMIO Base", HEX,=0D
+ Help "PCI Temporary PCI GFX Base used before full PCI enumeration.=
0x80000000(Default)."=0D
+ "Valid range: 0x80000000 ~ 0xDFFFFFFF"=0D
+EndPage=0D
+=0D
diff --git a/IntelFsp2Pkg/Tools/Tests/ExpectedOutput.yaml b/IntelFsp2Pkg/To=
ols/Tests/ExpectedOutput.yaml
new file mode 100644
index 0000000000..3594b9895e
--- /dev/null
+++ b/IntelFsp2Pkg/Tools/Tests/ExpectedOutput.yaml
@@ -0,0 +1,270 @@
+variable:=0D
+ PLATFORM_NAME : QemuFspPkg=0D
+ PLATFORM_GUID : 1BEDB57A-7904-406e-8486-C89FC7FB39EE=0D
+ PLATFORM_VERSION : 0.1=0D
+ DSC_SPECIFICATION : 0x00010005=0D
+ OUTPUT_DIRECTORY : Build/QemuFspPkg=0D
+ SUPPORTED_ARCHITECTURES : IA32|X64=0D
+ BUILD_TARGETS : DEBUG|RELEASE=0D
+ SKUID_IDENTIFIER : DEFAULT=0D
+ FLASH_DEFINITION : QemuFspPkg/QemuFspPkg.fdf=0D
+ FSP_T_UPD_TOOL_GUID : 34686CA3-34F9-4901-B82A-BA630F0714C6=0D
+ FSP_V_UPD_TOOL_GUID : 4E2F4725-734A-4399-BAF5-B4E16348EB2F=0D
+ FSP_M_UPD_TOOL_GUID : 39A250DB-E465-4DD1-A2AC-E2BD3C0E2385=0D
+ FSP_S_UPD_TOOL_GUID : CAE3605B-5B34-4C85-B3D7-27D54273C40F=0D
+ FSP_T_UPD_FFS_GUID : 70BCF6A5-FFB1-47D8-B1AE-EFE5508E23EA=0D
+ FSP_V_UPD_FFS_GUID : 0197EF5E-2FFC-4089-8E55-F70400B18146=0D
+ FSP_M_UPD_FFS_GUID : D5B86AEA-6AF7-40D4-8014-982301BC3D89=0D
+ FSP_S_UPD_FFS_GUID : E3CD9B18-998C-4F76-B65E-98B154E5446F=0D
+ FSP_PACKAGE : QemuFspPkg=0D
+ FSP_IMAGE_ID : 0x245053464D455124 # $QEMFSP$=0D
+ FSP_IMAGE_REV : 0x00001010=0D
+ CAR_BASE_ADDRESS : 0x00000000=0D
+ CAR_REGION_SIZE : 0x00080000=0D
+ CAR_BLD_REGION_SIZE : 0x00070000=0D
+ CAR_FSP_REGION_SIZE : 0x00010000=0D
+ FSP_ARCH : X64=0D
+=0D
+=0D
+template:=0D
+=0D
+=0D
+configs:=0D
+ - $ACTION :=0D
+ page : TMP::"FSP T", MEM::"FSP MemoryInit Settings", SIL::"F=
SP SiliconInit Settings"=0D
+ - $ACTION :=0D
+ find : QEMUPD_T=0D
+ - FSPT_UPD :=0D
+ - FSP_UPD_HEADER :=0D
+ - Signature :=0D
+ length : 0x08=0D
+ value : 0x545F4450554D4551=0D
+ - Revision :=0D
+ name : FsptUpdRevision=0D
+ length : 0x01=0D
+ value : 0x01=0D
+ - Reserved :=0D
+ length : 0x17=0D
+ value : {0x00}=0D
+ - FSPT_ARCH_UPD :=0D
+ - Revision :=0D
+ length : 0x01=0D
+ value : 0x01=0D
+ - Reserved :=0D
+ length : 0x03=0D
+ value : {0x00}=0D
+ - Length :=0D
+ length : 0x04=0D
+ value : 0x00000020=0D
+ - FspDebugHandler :=0D
+ length : 0x04=0D
+ value : 0x00000000=0D
+ - Reserved1 :=0D
+ length : 0x14=0D
+ value : {0x00}=0D
+ - FSPT_COMMON_UPD :=0D
+ - Revision :=0D
+ length : 0x01=0D
+ value : 0x01=0D
+ - Reserved :=0D
+ length : 0x03=0D
+ value : {0x00}=0D
+ - MicrocodeRegionBase :=0D
+ length : 0x04=0D
+ value : 0x00000000=0D
+ - MicrocodeRegionLength :=0D
+ length : 0x04=0D
+ value : 0x00000000=0D
+ - CodeRegionBase :=0D
+ length : 0x04=0D
+ value : 0x00000000=0D
+ - CodeRegionLength :=0D
+ length : 0x04=0D
+ value : 0x00000000=0D
+ - Reserved1 :=0D
+ length : 0x0C=0D
+ value : {0x00}=0D
+ - FSP_T_CONFIG :=0D
+ - $ACTION :=0D
+ page : TMP=0D
+ - ChickenBytes :=0D
+ name : Chicken bytes to test Hex config=0D
+ type : EditNum, HEX, (0x00000000,0xFFFFFFFF)=0D
+ help : >=0D
+ This option shows how to present option for 4 byt=
es data=0D
+ length : 0x04=0D
+ value : 0x00000000=0D
+ - ReservedFsptUpd1 :=0D
+ length : 0x1C=0D
+ value : {0x00}=0D
+ - UpdTerminator :=0D
+ length : 0x02=0D
+ value : 0x55AA=0D
+ - $ACTION :=0D
+ find : QEMUPD_M=0D
+ =0D
+ - FSPM_UPD :=0D
+ - FSP_UPD_HEADER :=0D
+ - Signature :=0D
+ length : 0x08=0D
+ value : 0x4D5F4450554D4551=0D
+ - Revision :=0D
+ name : FspmUpdRevision=0D
+ length : 0x01=0D
+ value : 0x01=0D
+ - Reserved :=0D
+ length : 0x17=0D
+ value : {0x00}=0D
+ - FSPM_ARCH_UPD :=0D
+ - Revision :=0D
+ length : 0x01=0D
+ value : 0x01=0D
+ - Reserved :=0D
+ length : 0x03=0D
+ value : {0x00}=0D
+ - NvsBufferPtr :=0D
+ struct : VOID*=0D
+ length : 0x04=0D
+ value : 0x00000000=0D
+ - StackBase :=0D
+ struct : VOID*=0D
+ name : StackBase=0D
+ help : >=0D
+ Stack base for FSP use. Default- 0xFEF16000=0D
+ length : 0x04=0D
+ value : $(CAR_BLD_REGION_SIZE)=0D
+ - StackSize :=0D
+ name : StackSize=0D
+ help : >=0D
+ To pass the stack size for FSP use. Bootloader ca=
n programmatically get the FSP requested StackSize by using the defaults in=
the FSP-M component. This is the minimum stack size expected by this revis=
ion of FSP. Default- 0x2A000=0D
+ length : 0x04=0D
+ value : $(CAR_FSP_REGION_SIZE)=0D
+ - BootLoaderTolumSize :=0D
+ name : BootLoaderTolumSize=0D
+ help : >=0D
+ To pass Bootloader Tolum size.=0D
+ length : 0x04=0D
+ value : 0x00000000=0D
+ - Bootmode :=0D
+ name : Bootmode=0D
+ help : >=0D
+ To maintain Bootmode details.=0D
+ length : 0x04=0D
+ value : 0x00000000=0D
+ - Reserved1 :=0D
+ length : 0x08=0D
+ value : {0x00}=0D
+ - FSP_M_CONFIG :=0D
+ - $ACTION :=0D
+ page : MEM=0D
+ - SerialDebugPortAddress :=0D
+ name : Debug Serial Port Base address=0D
+ type : EditNum, HEX, (0x00000000,0xFFFFFFFF)=0D
+ help : >=0D
+ Debug serial port base address. This option will =
be used only when the 'Serial Port Debug Device'=0D
+ option is set to 'External Device'. 0x00000000(De=
fault).=0D
+ length : 0x04=0D
+ value : 0x00000000=0D
+ - SerialDebugPortType :=0D
+ name : Debug Serial Port Type=0D
+ type : Combo=0D
+ option : 0:NONE, 1:I/O, 2:MMIO=0D
+ help : >=0D
+ 16550 compatible debug serial port resource type.=
NONE means no serial port support. 0x02:MMIO(Default).=0D
+ length : 0x01=0D
+ value : 0x02=0D
+ - SerialDebugPortDevice :=0D
+ name : Serial Port Debug Device=0D
+ type : Combo=0D
+ option : 0:SOC UART0, 1:SOC UART1, 2:SOC UART2, 3:External=
Device=0D
+ help : >=0D
+ Select active serial port device for debug. =0D
+ For SOC UART devices,'Debug Serial Port Base' opt=
ions will be ignored. 0x02:SOC UART2(Default).=0D
+ length : 0x01=0D
+ value : 0x02=0D
+ - SerialDebugPortStrideSize :=0D
+ name : Debug Serial Port Stride Size=0D
+ type : Combo=0D
+ option : 0:1, 2:4=0D
+ help : >=0D
+ Debug serial port register map stride size in byt=
es. 0x00:1, 0x02:4(Default).=0D
+ length : 0x01=0D
+ value : 0x02=0D
+ - ReservedFspmUpd :=0D
+ length : 0x04=0D
+ value : {0x00}=0D
+ - UpdTerminator :=0D
+ length : 0x02=0D
+ value : 0x55AA=0D
+ - $ACTION :=0D
+ find : QEMUPD_S=0D
+ =0D
+ - FSPS_UPD :=0D
+ - FSP_UPD_HEADER :=0D
+ - Signature :=0D
+ length : 0x08=0D
+ value : 0x535F4450554D4551=0D
+ - Revision :=0D
+ name : FspsUpdRevision=0D
+ length : 0x01=0D
+ value : 0x01=0D
+ - Reserved :=0D
+ length : 0x17=0D
+ value : {0x00}=0D
+ - FSPS_ARCH_UPD :=0D
+ - Revision :=0D
+ length : 0x01=0D
+ value : 0x01=0D
+ - Reserved :=0D
+ length : 0x03=0D
+ value : {0x00}=0D
+ - Length :=0D
+ length : 0x04=0D
+ value : 0x00000020=0D
+ - FspEventHandler :=0D
+ length : 0x04=0D
+ value : 0x00000000=0D
+ - EnableMultiPhaseSiliconInit :=0D
+ length : 0x01=0D
+ value : 0x00=0D
+ - Reserved1 :=0D
+ length : 0x13=0D
+ value : {0x00}=0D
+ - FSP_S_CONFIG :=0D
+ - $ACTION :=0D
+ page : SIL=0D
+ - LogoSize :=0D
+ name : BMP Logo Data Size=0D
+ type : Reserved=0D
+ help : >=0D
+ BMP logo data buffer size. 0x00000000(Default).=0D
+ length : 0x04=0D
+ value : 0x00000000=0D
+ - LogoPtr :=0D
+ name : BMP Logo Data Pointer=0D
+ type : Reserved=0D
+ help : >=0D
+ BMP logo data pointer to a BMP format buffer. 0x0=
0000000(Default).=0D
+ length : 0x04=0D
+ value : 0x00000000=0D
+ - GraphicsConfigPtr :=0D
+ name : Graphics Configuration Data Pointer=0D
+ type : Reserved=0D
+ help : >=0D
+ Graphics configuration data used for initializati=
on. 0x00000000(Default).=0D
+ length : 0x04=0D
+ value : 0x00000000=0D
+ - PciTempResourceBase :=0D
+ name : PCI GFX Temporary MMIO Base=0D
+ type : EditNum, HEX, (0x80000000,0xDFFFFFFF)=0D
+ help : >=0D
+ PCI Temporary PCI GFX Base used before full PCI e=
numeration. 0x80000000(Default).=0D
+ length : 0x04=0D
+ value : 0x80000000=0D
+ - ReservedFspsUpd :=0D
+ length : 0x01=0D
+ value : 0x00=0D
+ - UpdTerminator :=0D
+ length : 0x02=0D
+ value : 0x55AA=0D
+ =0D
diff --git a/IntelFsp2Pkg/Tools/Tests/QemuFspPkg.dsc b/IntelFsp2Pkg/Tools/T=
ests/QemuFspPkg.dsc
new file mode 100644
index 0000000000..af0bd4e717
--- /dev/null
+++ b/IntelFsp2Pkg/Tools/Tests/QemuFspPkg.dsc
@@ -0,0 +1,469 @@
+## @file=0D
+# FSP DSC build file for QEMU platform=0D
+#=0D
+# Copyright (c) 2017 - 2021, Intel Corporation. All rights reserved.<BR>=0D
+#=0D
+# This program and the accompanying materials=0D
+# are licensed and made available under the terms and conditions of the=
BSD License=0D
+# which accompanies this distribution. The full text of the license may=
be found at=0D
+# http://opensource.org/licenses/bsd-license.php=0D
+#=0D
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,=
=0D
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR =
IMPLIED.=0D
+#=0D
+##=0D
+=0D
+##########################################################################=
######=0D
+#=0D
+# Defines Section - statements that will be processed to create a Makefile=
.=0D
+#=0D
+##########################################################################=
######=0D
+[Defines]=0D
+ PLATFORM_NAME =3D QemuFspPkg=0D
+ PLATFORM_GUID =3D 1BEDB57A-7904-406e-8486-C89FC7FB39EE=
=0D
+ PLATFORM_VERSION =3D 0.1=0D
+ DSC_SPECIFICATION =3D 0x00010005=0D
+ OUTPUT_DIRECTORY =3D Build/QemuFspPkg=0D
+ SUPPORTED_ARCHITECTURES =3D IA32|X64=0D
+ BUILD_TARGETS =3D DEBUG|RELEASE=0D
+ SKUID_IDENTIFIER =3D DEFAULT=0D
+ FLASH_DEFINITION =3D QemuFspPkg/QemuFspPkg.fdf=0D
+=0D
+ #=0D
+ # UPD tool definition=0D
+ #=0D
+ FSP_T_UPD_TOOL_GUID =3D 34686CA3-34F9-4901-B82A-BA630F0714C6=
=0D
+ FSP_V_UPD_TOOL_GUID =3D 4E2F4725-734A-4399-BAF5-B4E16348EB2F=
=0D
+ FSP_M_UPD_TOOL_GUID =3D 39A250DB-E465-4DD1-A2AC-E2BD3C0E2385=
=0D
+ FSP_S_UPD_TOOL_GUID =3D CAE3605B-5B34-4C85-B3D7-27D54273C40F=
=0D
+ FSP_T_UPD_FFS_GUID =3D 70BCF6A5-FFB1-47D8-B1AE-EFE5508E23EA=
=0D
+ FSP_V_UPD_FFS_GUID =3D 0197EF5E-2FFC-4089-8E55-F70400B18146=
=0D
+ FSP_M_UPD_FFS_GUID =3D D5B86AEA-6AF7-40D4-8014-982301BC3D89=
=0D
+ FSP_S_UPD_FFS_GUID =3D E3CD9B18-998C-4F76-B65E-98B154E5446F=
=0D
+=0D
+ #=0D
+ # Set platform specific package/folder name, same as passed from PREBUIL=
D script.=0D
+ # PLATFORM_PACKAGE would be the same as PLATFORM_NAME as well as package=
build folder=0D
+ # DEFINE only takes effect at R9 DSC and FDF.=0D
+ #=0D
+ DEFINE FSP_PACKAGE =3D QemuFspPkg=0D
+ DEFINE FSP_IMAGE_ID =3D 0x245053464D455124 # $QEMFSP=
$=0D
+ DEFINE FSP_IMAGE_REV =3D 0x00001010=0D
+=0D
+ DEFINE CAR_BASE_ADDRESS =3D 0x00000000=0D
+ DEFINE CAR_REGION_SIZE =3D 0x00080000=0D
+ DEFINE CAR_BLD_REGION_SIZE =3D 0x00070000=0D
+ DEFINE CAR_FSP_REGION_SIZE =3D 0x00010000=0D
+=0D
+ DEFINE FSP_ARCH =3D X64=0D
+=0D
+##########################################################################=
######=0D
+#=0D
+# SKU Identification section - list of all SKU IDs supported by this=0D
+# Platform.=0D
+#=0D
+##########################################################################=
######=0D
+[SkuIds]=0D
+ 0|DEFAULT # The entry: 0|DEFAULT is reserved and always req=
uired.=0D
+=0D
+##########################################################################=
######=0D
+#=0D
+# Library Class section - list of all Library Classes needed by this Platf=
orm.=0D
+#=0D
+##########################################################################=
######=0D
+=0D
+[LibraryClasses]=0D
+ PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf=
=0D
+ PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf=0D
+ DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseD=
ebugPrintErrorLevelLib.inf=0D
+ BaseLib|MdePkg/Library/BaseLib/BaseLib.inf=0D
+ IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf=0D
+ PciLib|MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf=0D
+ PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf=0D
+ PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf=0D
+ BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf=
=0D
+ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf=0D
+ PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf=0D
+ HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf=0D
+ PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/=
PeiServicesTablePointerLibIdt.inf=0D
+ PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf=0D
+ MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAlloc=
ationLib.inf=0D
+ PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeC=
offGetEntryPointLib.inf=0D
+ ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiRepor=
tStatusCodeLib.inf=0D
+ CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMain=
tenanceLib.inf=0D
+ PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf=0D
+ PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeC=
offExtraActionLibNull.inf=0D
+ UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompres=
sLib.inf=0D
+ SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchroniza=
tionLib.inf=0D
+ CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf=0D
+ ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExt=
ractGuidedSectionLib.inf=0D
+ CacheLib|IntelFsp2Pkg/Library/BaseCacheLib/BaseCacheLib.inf=0D
+ CacheAsRamLib|IntelFsp2Pkg/Library/BaseCacheAsRamLibNull/BaseCacheAsRamL=
ibNull.inf=0D
+ FspSwitchStackLib|IntelFsp2Pkg/Library/BaseFspSwitchStackLib/BaseFspSwit=
chStackLib.inf=0D
+ FspCommonLib|IntelFsp2Pkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf=
=0D
+ FspPlatformLib|IntelFsp2Pkg/Library/BaseFspPlatformLib/BaseFspPlatformLi=
b.inf=0D
+ PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatfor=
mHookLibNull.inf=0D
+ PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibN=
ull.inf=0D
+ OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHo=
okStatusCodeLibNull.inf=0D
+ UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf=0D
+!if $(TARGET) =3D=3D DEBUG=0D
+ DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.in=
f=0D
+ SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPort=
Lib16550.inf=0D
+!else=0D
+ DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf=0D
+ SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull=
.inf=0D
+!endif=0D
+=0D
+=0D
+##########################################################################=
######=0D
+#=0D
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform=0D
+#=0D
+##########################################################################=
######=0D
+[PcdsFixedAtBuild]=0D
+ gEfiMdeModulePkgTokenSpaceGuid.PcdShadowPeimOnS3Boot | TRUE=0D
+ gQemuFspPkgTokenSpaceGuid.PcdFspHeaderRevision | 0x03=0D
+ gQemuFspPkgTokenSpaceGuid.PcdFspImageIdString | $(FSP_IMAGE_ID=
)=0D
+ gQemuFspPkgTokenSpaceGuid.PcdFspImageRevision | $(FSP_IMAGE_RE=
V)=0D
+ #=0D
+ # FSP CAR Usages (BL RAM | FSP RAM | FSP CODE)=0D
+ #=0D
+ gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase | $(CAR_BASE_ADD=
RESS)=0D
+ gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize | $(CAR_REGION_S=
IZE)=0D
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspTemporaryRamSize | $(CAR_FSP_REGI=
ON_SIZE)=0D
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspReservedBufferSize | 0x0100=0D
+=0D
+ # This defines how much space will be used for heap in FSP temporary mem=
ory=0D
+ # x % of FSP temporary memory will be used for heap=0D
+ # (100 - x) % of FSP temporary memory will be used for stack=0D
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspHeapSizePercentage | 65=0D
+=0D
+ # This is a platform specific global pointer used by FSP=0D
+ gIntelFsp2PkgTokenSpaceGuid.PcdGlobalDataPointerAddress | 0xFED00148=0D
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspReservedMemoryLength | 0x00100000=0D
+=0D
+!if $(TARGET) =3D=3D RELEASE=0D
+ gEfiMdePkgTokenSpaceGuid.PcdFixedDebugPrintErrorLevel | 0x00000000=0D
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask | 0=0D
+!else=0D
+ gEfiMdePkgTokenSpaceGuid.PcdFixedDebugPrintErrorLevel | 0x80000047=0D
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask | 0x27=0D
+!endif=0D
+=0D
+[PcdsPatchableInModule]=0D
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress | 0xE0000000=0D
+ #=0D
+ # This entry will be patched during the build process=0D
+ #=0D
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress | 0x12345678=0D
+=0D
+!if $(TARGET) =3D=3D RELEASE=0D
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel | 0=0D
+!else=0D
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel | 0x80000047=0D
+!endif=0D
+=0D
+[PcdsDynamicVpd.Upd]=0D
+ #=0D
+ # This section is not used by the normal build process=0D
+ # However, FSP will use dedicated tool to handle it and generate a=0D
+ # VPD similar binary block (User Configuration Data). This block will=0D
+ # be accessed through a generated data structure directly rather than=0D
+ # PCD services. This is for size consideration.=0D
+ # Format:=0D
+ # gQemuFspPkgTokenSpaceGuid.Updxxxxxxxxxxxxn | OFFSET | LENGTH | =
VALUE=0D
+ # Only simple data type is supported=0D
+ #=0D
+=0D
+ #=0D
+ # Comments with !BSF will be used to generate BSF file=0D
+ # Comments with !HDR will be used to generate H header file=0D
+ #=0D
+=0D
+ # Global definitions in BSF=0D
+ # !BSF PAGES:{TMP:"FSP T", MEM:"FSP MemoryInit Settings", SIL:"FSP Silic=
onInit Settings"}=0D
+ # !BSF BLOCK:{NAME:"QEMU Platform", VER:"0.1"}=0D
+=0D
+ # !BSF FIND:{QEMUPD_T}=0D
+ # !HDR COMMENT:{FSP_UPD_HEADER:FSP UPD Header}=0D
+ # !HDR EMBED:{FSP_UPD_HEADER:FspUpdHeader:START}=0D
+ # FsptUpdSignature: {QEMUPD_T}=0D
+ gQemuFspPkgTokenSpaceGuid.Signature | * | 0x08 | 0x545=
F4450554D4551=0D
+ # !BSF NAME:{FsptUpdRevision}=0D
+ gQemuFspPkgTokenSpaceGuid.Revision | * | 0x01 | 0x01=
=0D
+ # !HDR EMBED:{FSP_UPD_HEADER:FspUpdHeader:END}=0D
+ gQemuFspPkgTokenSpaceGuid.Reserved | * | 0x17 | {0x00=
}=0D
+=0D
+ # !HDR COMMENT:{FSPT_ARCH_UPD:FSPT_ARCH_UPD}=0D
+ # !HDR EMBED:{FSPT_ARCH_UPD:FsptArchUpd:START}=0D
+ gQemuFspPkgTokenSpaceGuid.Revision | * | 0x01 | 0x01=
=0D
+ gQemuFspPkgTokenSpaceGuid.Reserved | * | 0x03 | {0x00=
}=0D
+ gQemuFspPkgTokenSpaceGuid.Length | * | 0x04 | 0x000=
00020=0D
+ gQemuFspPkgTokenSpaceGuid.FspDebugHandler | * | 0x04 | 0x000=
00000=0D
+ # !HDR EMBED:{FSPT_ARCH_UPD:FsptArchUpd:END}=0D
+ gQemuFspPkgTokenSpaceGuid.Reserved1 | * | 0x14 | {0x00=
}=0D
+=0D
+ # !HDR COMMENT:{FSPT_COMMON_UPD:Fsp T Common UPD}=0D
+ # !HDR EMBED:{FSPT_COMMON_UPD:FsptCommonUpd:START}=0D
+ gQemuFspPkgTokenSpaceGuid.Revision | * | 0x01 | 0x01=
=0D
+ gQemuFspPkgTokenSpaceGuid.Reserved | * | 0x03 | {0x00=
}=0D
+=0D
+ # Base address of the microcode region.=0D
+ gQemuFspPkgTokenSpaceGuid.MicrocodeRegionBase | * | 0x04 | 0x000=
00000=0D
+=0D
+ # Length of the microcode region.=0D
+ gQemuFspPkgTokenSpaceGuid.MicrocodeRegionLength | * | 0x04 | 0x000=
00000=0D
+=0D
+ # Base address of the cacheable flash region.=0D
+ gQemuFspPkgTokenSpaceGuid.CodeRegionBase | * | 0x04 | 0x000=
00000=0D
+=0D
+ # Length of the cacheable flash region.=0D
+ gQemuFspPkgTokenSpaceGuid.CodeRegionLength | * | 0x04 | 0x000=
00000=0D
+=0D
+ # !HDR EMBED:{FSPT_COMMON_UPD:FsptCommonUpd:END}=0D
+ gQemuFspPkgTokenSpaceGuid.Reserved1 | * | 0x0C | {0x00=
}=0D
+=0D
+ # !HDR COMMENT:{FSP_T_CONFIG:Fsp T Configuration}=0D
+ # !HDR EMBED:{FSP_T_CONFIG:FsptConfig:START}=0D
+ # !BSF PAGE:{TMP}=0D
+ # !BSF NAME:{Chicken bytes to test Hex config}=0D
+ # !BSF TYPE:{EditNum, HEX, (0x00000000,0xFFFFFFFF)}=0D
+ # !BSF HELP:{This option shows how to present option for 4 bytes data}=0D
+ gQemuFspPkgTokenSpaceGuid.ChickenBytes | * | 0x04 | 0x000=
00000=0D
+=0D
+ # !HDR EMBED:{FSP_T_CONFIG:FsptConfig:END}=0D
+ gQemuFspPkgTokenSpaceGuid.ReservedFsptUpd1 | * | 0x1C | {0x00=
}=0D
+=0D
+ # Note please keep "UpdTerminator" at the end of each UPD region.=0D
+ # The tool will use this field to determine the actual end of the UPD da=
ta=0D
+ # structure.=0D
+ gQemuFspPkgTokenSpaceGuid.UpdTerminator | * | 0x02 | 0x55A=
A=0D
+=0D
+ ########################################################################=
########=0D
+ #=0D
+ # UPDs consumed in FspMemoryInit Api=0D
+ #=0D
+ ########################################################################=
########=0D
+ # !BSF FIND:{QEMUPD_M}=0D
+ # !HDR COMMENT:{FSP_UPD_HEADER:FSP UPD Header}=0D
+ # !HDR EMBED:{FSP_UPD_HEADER:FspUpdHeader:START}=0D
+ # FspmUpdSignature: {QEMUPD_M}=0D
+ gQemuFspPkgTokenSpaceGuid.Signature | * | 0x08 | 0x4D5=
F4450554D4551=0D
+ # !BSF NAME:{FspmUpdRevision}=0D
+ gQemuFspPkgTokenSpaceGuid.Revision | * | 0x01 | 0x01=
=0D
+ # !HDR EMBED:{FSP_UPD_HEADER:FspUpdHeader:END}=0D
+ gQemuFspPkgTokenSpaceGuid.Reserved | * | 0x17 | {0x00=
}=0D
+=0D
+ # !HDR COMMENT:{FSPM_ARCH_UPD:Fsp M Architectural UPD}=0D
+ # !HDR EMBED:{FSPM_ARCH_UPD:FspmArchUpd:START}=0D
+=0D
+ gQemuFspPkgTokenSpaceGuid.Revision | * | 0x01 | 0x01=
=0D
+=0D
+ gQemuFspPkgTokenSpaceGuid.Reserved | * | 0x03 | {0x00=
}=0D
+=0D
+ # !HDR STRUCT:{VOID*}=0D
+ gQemuFspPkgTokenSpaceGuid.NvsBufferPtr | * | 0x04 | 0x000=
00000=0D
+=0D
+ # !HDR STRUCT:{VOID*}=0D
+ # !BSF NAME:{StackBase}=0D
+ # !BSF HELP:{Stack base for FSP use. Default: 0xFEF16000}=0D
+ gQemuFspPkgTokenSpaceGuid.StackBase | * | 0x04 | $(CAR=
_BLD_REGION_SIZE)=0D
+=0D
+ # !BSF NAME:{StackSize}=0D
+ # !BSF HELP:{To pass the stack size for FSP use. Bootloader can programm=
atically get the FSP requested StackSize by using the defaults in the FSP-M=
component. This is the minimum stack size expected by this revision of FSP=
. Default: 0x2A000}=0D
+ gQemuFspPkgTokenSpaceGuid.StackSize | * | 0x04 | $(CAR=
_FSP_REGION_SIZE)=0D
+=0D
+ # !BSF NAME:{BootLoaderTolumSize}=0D
+ # !BSF HELP:{To pass Bootloader Tolum size.}=0D
+ gQemuFspPkgTokenSpaceGuid.BootLoaderTolumSize | * | 0x04 | 0x000=
00000=0D
+=0D
+ # !BSF NAME:{Bootmode}=0D
+ # !BSF HELP:{To maintain Bootmode details.}=0D
+ gPlatformFspPkgTokenSpaceGuid.Bootmode | * | 0x04 | 0x=
00000000=0D
+=0D
+ # !HDR EMBED:{FSPM_ARCH_UPD:FspmArchUpd:END}=0D
+ gQemuFspPkgTokenSpaceGuid.Reserved1 | * | 0x08 | {0x00=
}=0D
+=0D
+ # !HDR COMMENT:{FSP_M_CONFIG:Fsp M Configuration}=0D
+ # !HDR EMBED:{FSP_M_CONFIG:FspmConfig:START}=0D
+ # !BSF PAGE:{MEM}=0D
+ # !BSF NAME:{Debug Serial Port Base address}=0D
+ # !BSF TYPE:{EditNum, HEX, (0x00000000,0xFFFFFFFF)}=0D
+ # !BSF HELP:{Debug serial port base address. This option will be used on=
ly when the 'Serial Port Debug Device'}=0D
+ # !BSF HELP:{+ option is set to 'External Device'. 0x00000000(Default).}=
=0D
+ gQemuFspPkgTokenSpaceGuid.SerialDebugPortAddress | * | 0x04 | 0x000=
00000=0D
+=0D
+ # !BSF NAME:{Debug Serial Port Type} TYPE:{Combo}=0D
+ # !BSF OPTION:{0:NONE, 1:I/O, 2:MMIO}=0D
+ # !BSF HELP:{16550 compatible debug serial port resource type. NONE mean=
s no serial port support. 0x02:MMIO(Default).}=0D
+ gQemuFspPkgTokenSpaceGuid.SerialDebugPortType | * | 0x01 | 0x02=
=0D
+=0D
+ # !BSF NAME:{Serial Port Debug Device} TYPE:{Combo}=0D
+ # !BSF OPTION:{0:SOC UART0, 1:SOC UART1, 2:SOC UART2, 3:External Device}=
=0D
+ # !BSF HELP:{Select active serial port device for debug. }=0D
+ # !BSF HELP:{+For SOC UART devices,'Debug Serial Port Base' options will=
be ignored. 0x02:SOC UART2(Default).}=0D
+ gQemuFspPkgTokenSpaceGuid.SerialDebugPortDevice | * | 0x01 | 0x02=
=0D
+=0D
+ # !BSF NAME:{Debug Serial Port Stride Size} TYPE:{Combo}=0D
+ # !BSF OPTION:{0:1, 2:4}=0D
+ # !BSF HELP:{Debug serial port register map stride size in bytes. 0x00:1=
, 0x02:4(Default).}=0D
+ gQemuFspPkgTokenSpaceGuid.SerialDebugPortStrideSize | * | 0x01 | 0x02=
=0D
+=0D
+=0D
+ # !HDR EMBED:{FSP_M_CONFIG:FspmConfig:END}=0D
+ gQemuFspPkgTokenSpaceGuid.ReservedFspmUpd | * | 0x04 | {0x00=
}=0D
+=0D
+=0D
+ # Note please keep "UpdTerminator" at the end of each UPD region.=0D
+ # The tool will use this field to determine the actual end of the UPD da=
ta=0D
+ # structure.=0D
+ gQemuFspPkgTokenSpaceGuid.UpdTerminator | * | 0x02 | 0x55A=
A=0D
+=0D
+ ########################################################################=
########=0D
+ #=0D
+ # UPDs consumed in FspSiliconInit Api=0D
+ #=0D
+ ########################################################################=
########=0D
+ # !BSF FIND:{QEMUPD_S}=0D
+ # !HDR COMMENT:{FSP_UPD_HEADER:FSP UPD Header}=0D
+ # !HDR EMBED:{FSP_UPD_HEADER:FspUpdHeader:START}=0D
+ # FspsUpdSignature: {QEMUPD_S}=0D
+ gQemuFspPkgTokenSpaceGuid.Signature | * | 0x08 | 0x535=
F4450554D4551=0D
+ # !BSF NAME:{FspsUpdRevision}=0D
+ gQemuFspPkgTokenSpaceGuid.Revision | * | 0x01 | 0x01=
=0D
+ # !HDR EMBED:{FSP_UPD_HEADER:FspUpdHeader:END}=0D
+ gQemuFspPkgTokenSpaceGuid.Reserved | * | 0x17 | {0x00=
}=0D
+=0D
+ # !HDR COMMENT:{FSPS_ARCH_UPD:FSPS_ARCH_UPD}=0D
+ # !HDR EMBED:{FSPS_ARCH_UPD:FspsArchUpd:START}=0D
+ gQemuFspPkgTokenSpaceGuid.Revision | * | 0x01 | 0x01=
=0D
+ gQemuFspPkgTokenSpaceGuid.Reserved | * | 0x03 | {0x00=
}=0D
+ gQemuFspPkgTokenSpaceGuid.Length | * | 0x04 | 0x000=
00020=0D
+ gQemuFspPkgTokenSpaceGuid.FspEventHandler | * | 0x04 | 0x000=
00000=0D
+ gQemuFspPkgTokenSpaceGuid.EnableMultiPhaseSiliconInit | * | 0x01 | 0x00=
=0D
+ # !HDR EMBED:{FSPS_ARCH_UPD:FspsArchUpd:END}=0D
+ gQemuFspPkgTokenSpaceGuid.Reserved1 | * | 0x13 | {0x00=
}=0D
+=0D
+ # !HDR COMMENT:{FSP_S_CONFIG:Fsp S Configuration}=0D
+ # !HDR EMBED:{FSP_S_CONFIG:FspsConfig:START}=0D
+ # !BSF PAGE:{SIL}=0D
+=0D
+ # !BSF NAME:{BMP Logo Data Size}=0D
+ # !BSF TYPE:{Reserved}=0D
+ # !BSF HELP:{BMP logo data buffer size. 0x00000000(Default).}=0D
+ gQemuFspPkgTokenSpaceGuid.LogoSize | * | 0x04 | 0x000=
00000=0D
+=0D
+ # !BSF NAME:{BMP Logo Data Pointer}=0D
+ # !BSF TYPE:{Reserved}=0D
+ # !BSF HELP:{BMP logo data pointer to a BMP format buffer. 0x00000000(De=
fault).}=0D
+ gQemuFspPkgTokenSpaceGuid.LogoPtr | * | 0x04 | 0x000=
00000=0D
+=0D
+ # !BSF NAME:{Graphics Configuration Data Pointer}=0D
+ # !BSF TYPE:{Reserved}=0D
+ # !BSF HELP:{Graphics configuration data used for initialization. 0x0000=
0000(Default).}=0D
+ gQemuFspPkgTokenSpaceGuid.GraphicsConfigPtr | * | 0x04 | 0x000=
00000=0D
+=0D
+ # !BSF NAME:{PCI GFX Temporary MMIO Base}=0D
+ # !BSF TYPE:{EditNum, HEX, (0x80000000,0xDFFFFFFF)}=0D
+ # !BSF HELP:{PCI Temporary PCI GFX Base used before full PCI enumeration=
. 0x80000000(Default).}=0D
+ gQemuFspPkgTokenSpaceGuid.PciTempResourceBase | * | 0x04 | 0x800=
00000=0D
+=0D
+ # !HDR EMBED:{FSP_S_CONFIG:FspsConfig:END}=0D
+ gQemuFspPkgTokenSpaceGuid.ReservedFspsUpd | * | 0x01 | 0x00=
=0D
+=0D
+ # Note please keep "UpdTerminator" at the end of each UPD region.=0D
+ # The tool will use this field to determine the actual end of the UPD da=
ta=0D
+ # structure.=0D
+ gQemuFspPkgTokenSpaceGuid.UpdTerminator | * | 0x02 | 0x55A=
A=0D
+=0D
+##########################################################################=
#########################=0D
+#=0D
+# Components Section - list of the modules and components that will be pro=
cessed by compilation=0D
+# tools and the EDK II tools to generate PE32/PE32+/C=
off image files.=0D
+#=0D
+# Note: The EDK II DSC file is not used to specify how compiled binary ima=
ges get placed=0D
+# into firmware volume images. This section is just a list of module=
s to compile from=0D
+# source into UEFI-compliant binaries.=0D
+# It is the FDF file that contains information on combining binary f=
iles into firmware=0D
+# volume images, whose concept is beyond UEFI and is described in PI=
specification.=0D
+# Binary modules do not need to be listed in this section, as they s=
hould be=0D
+# specified in the FDF file. For example: Shell binary (Shell_Full.e=
fi), FAT binary (Fat.efi),=0D
+# Logo (Logo.bmp), and etc.=0D
+# There may also be modules listed in this section that are not requ=
ired in the FDF file,=0D
+# When a module listed here is excluded from FDF file, then UEFI-com=
pliant binary will be=0D
+# generated for it, but the binary will not be put into any firmware=
volume.=0D
+#=0D
+##########################################################################=
#########################=0D
+[Components.IA32]=0D
+ #=0D
+ # FSP Binary Components=0D
+ #=0D
+ $(FSP_PACKAGE)/FspHeader/FspHeader.inf=0D
+=0D
+ #=0D
+ # SEC=0D
+ #=0D
+ IntelFsp2Pkg/FspSecCore/FspSecCoreT.inf {=0D
+ <LibraryClasses>=0D
+ FspSecPlatformLib|$(FSP_PACKAGE)/Library/PlatformSecLib/Vtf0Platform=
SecTLib.inf=0D
+ }=0D
+=0D
+[Components.$(FSP_ARCH)]=0D
+ IntelFsp2Pkg/FspSecCore/FspSecCoreV.inf {=0D
+ <LibraryClasses>=0D
+ FspSecPlatformLib|$(FSP_PACKAGE)/Library/PlatformSecLib/Vtf0Platform=
SecVLib.inf=0D
+ }=0D
+=0D
+ IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf {=0D
+ <LibraryClasses>=0D
+ FspSecPlatformLib|$(FSP_PACKAGE)/Library/PlatformSecLib/Vtf0Platform=
SecMLib.inf=0D
+ }=0D
+=0D
+ IntelFsp2Pkg/FspSecCore/FspSecCoreS.inf {=0D
+ <LibraryClasses>=0D
+ FspSecPlatformLib|$(FSP_PACKAGE)/Library/PlatformSecLib/Vtf0Platform=
SecSLib.inf=0D
+ }=0D
+=0D
+ #=0D
+ # PEI Core=0D
+ #=0D
+ MdeModulePkg/Core/Pei/PeiMain.inf=0D
+=0D
+ #=0D
+ # PCD=0D
+ #=0D
+ MdeModulePkg/Universal/PCD/Pei/Pcd.inf {=0D
+ <LibraryClasses>=0D
+ DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf=0D
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf=0D
+ }=0D
+=0D
+ $(FSP_PACKAGE)/FspvInit/FspvInit.inf=0D
+ $(FSP_PACKAGE)/FspmInit/FspmInit.inf=0D
+ $(FSP_PACKAGE)/FspsInit/FspsInit.inf=0D
+ $(FSP_PACKAGE)/QemuVideo/QemuVideo.inf=0D
+ MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {=0D
+ <LibraryClasses>=0D
+ DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNu=
ll.inf=0D
+ ResetSystemLib|MdeModulePkg/Library/BaseResetSystemLibNull/BaseReset=
SystemLibNull.inf=0D
+ }=0D
+ IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.inf=0D
+=0D
+##########################################################################=
#########################=0D
+#=0D
+# BuildOptions Section - Define the module specific tool chain flags that =
should be used as=0D
+# the default flags for a module. These flags are a=
ppended to any=0D
+# standard flags that are defined by the build proc=
ess. They can be=0D
+# applied for any modules or only those modules wit=
h the specific=0D
+# module style (EDK or EDKII) specified in [Compone=
nts] section.=0D
+#=0D
+##########################################################################=
#########################=0D
+[BuildOptions]=0D
+# Append build options for EDK and EDKII drivers (=3D is Append, =3D=3D is=
Replace)=0D
+ # Enable link-time optimization when building with GCC49=0D
+ *_GCC49_IA32_CC_FLAGS =3D -flto=0D
+ *_GCC49_IA32_DLINK_FLAGS =3D -flto=0D
+ *_GCC5_IA32_CC_FLAGS =3D -fno-pic=0D
+ *_GCC5_IA32_DLINK_FLAGS =3D -no-pie=0D
+ *_GCC5_IA32_ASLCC_FLAGS =3D -fno-pic=0D
+ *_GCC5_IA32_ASLDLINK_FLAGS =3D -no-pie=0D
diff --git a/IntelFsp2Pkg/Tools/Tests/test_yaml.py b/IntelFsp2Pkg/Tools/Tes=
ts/test_yaml.py
new file mode 100644
index 0000000000..d81d7f7c4e
--- /dev/null
+++ b/IntelFsp2Pkg/Tools/Tests/test_yaml.py
@@ -0,0 +1,96 @@
+# @file=0D
+# Split a file into two pieces at the request offset.=0D
+#=0D
+# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>=0D
+#=0D
+# SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+#=0D
+##=0D
+=0D
+# Import Modules=0D
+import unittest=0D
+import tempfile=0D
+import os=0D
+import shutil=0D
+import struct as st=0D
+import filecmp=0D
+=0D
+import os, sys=0D
+currentdir =3D os.path.dirname(os.path.realpath(__file__))=0D
+parentdir =3D os.path.dirname(currentdir)=0D
+sys.path.append(parentdir)=0D
+import FspDscBsf2Yaml=0D
+=0D
+YamlHeaderLineLength =3D 10=0D
+HdrFileHeaderLineLength =3D 32=0D
+BsfFileHeaderLineLength =3D 19=0D
+=0D
+def GenFileWithoutHdr(inputfile, numLineToStrip):=0D
+ yaml_file =3D open(inputfile, "r")=0D
+ lines =3D yaml_file.readlines()=0D
+ yaml_file.close()=0D
+ del lines[:numLineToStrip]=0D
+=0D
+ noHdrOutputFileName =3D "no-header-" + inputfile=0D
+ stripped_file =3D open(noHdrOutputFileName, "w")=0D
+ for line in lines:=0D
+ stripped_file.write(line)=0D
+ stripped_file.close()=0D
+ return noHdrOutputFileName=0D
+=0D
+class TestFspScripts(unittest.TestCase):=0D
+ def test_generateFspHeader_fromDsc(self):=0D
+ # Generate HEADER=0D
+ cmd =3D '{} {} HEADER {} {} {}'.format(=0D
+ 'python',=0D
+ '..\GenCfgOpt.py',=0D
+ 'QemuFspPkg.dsc',=0D
+ '.',=0D
+ "")=0D
+ os.system(cmd)=0D
+ noHdrOutputFileName =3D GenFileWithoutHdr("FspUpd.h", HdrFileHeade=
rLineLength)=0D
+ self.assertTrue(filecmp.cmp(noHdrOutputFileName,=0D
+ 'ExpectedFspUpd.h'))=0D
+=0D
+ def test_generateFspsHeader_fromDsc(self):=0D
+ noHdrOutputFileName =3D GenFileWithoutHdr("FspsUpd.h", HdrFileHead=
erLineLength)=0D
+ self.assertTrue(filecmp.cmp(noHdrOutputFileName,=0D
+ 'ExpectedFspsUpd.h'))=0D
+=0D
+ def test_generateFsptHeader_fromDsc(self):=0D
+ noHdrOutputFileName =3D GenFileWithoutHdr("FsptUpd.h", HdrFileHead=
erLineLength)=0D
+ self.assertTrue(filecmp.cmp(noHdrOutputFileName,=0D
+ 'ExpectedFsptUpd.h'))=0D
+=0D
+ def test_generateFspmHeader_fromDsc(self):=0D
+ noHdrOutputFileName =3D GenFileWithoutHdr("FspmUpd.h", HdrFileHead=
erLineLength)=0D
+ self.assertTrue(filecmp.cmp(noHdrOutputFileName,=0D
+ 'ExpectedFspmUpd.h'))=0D
+=0D
+ def test_generateBsf_fromDsc(self):=0D
+ # Generate BSF=0D
+ cmd =3D '{} {} GENBSF {} {} {}'.format(=0D
+ 'python',=0D
+ '..\GenCfgOpt.py',=0D
+ 'QemuFspPkg.dsc',=0D
+ '.',=0D
+ "Output.bsf")=0D
+ os.system(cmd)=0D
+ noHdrOutputFileName =3D GenFileWithoutHdr("Output.bsf", BsfFileHea=
derLineLength)=0D
+ self.assertTrue(filecmp.cmp(noHdrOutputFileName,=0D
+ 'ExpectedOutput.bsf'))=0D
+=0D
+ def test_generateYaml_fromDsc(self):=0D
+ # Generate YAML=0D
+ cmd =3D '{} {} {} {}'.format(=0D
+ 'python',=0D
+ '..\FspDscBsf2Yaml.py',=0D
+ 'QemuFspPkg.dsc',=0D
+ "Output.yaml")=0D
+ os.system(cmd)=0D
+ noHdrOutputFileName =3D GenFileWithoutHdr("Output.yaml", YamlHeade=
rLineLength)=0D
+ self.assertTrue(filecmp.cmp(noHdrOutputFileName,=0D
+ 'ExpectedOutput.yaml'))=0D
+=0D
+if __name__ =3D=3D '__main__':=0D
+ unittest.main()=0D
diff --git a/IntelFsp2Pkg/Tools/UserManuals/FspDscBsf2YamlUserManual.md b/I=
ntelFsp2Pkg/Tools/UserManuals/FspDscBsf2YamlUserManual.md
new file mode 100644
index 0000000000..ba2311445c
--- /dev/null
+++ b/IntelFsp2Pkg/Tools/UserManuals/FspDscBsf2YamlUserManual.md
@@ -0,0 +1,39 @@
+#Name=0D
+**FspDscBsf2Yaml.py** The python script that generates YAML file for=0D
+the Boot Settings from an EDK II Platform Description (**DSC**) file=0D
+or from a Boot Settings File (**BSF**). It is created to help=0D
+transitioning FSP Updateable Product Data (**UPD**) file format to=0D
+new standardized YAML format so that it can be configured through=0D
+open source tools.=0D
+=0D
+#Synopsis=0D
+```=0D
+FspDscBsf2Yaml DscFile|BsfFile YamlFile=0D
+```=0D
+=0D
+#Description=0D
+**FspDscBsf2Yaml.py** is a script that generates configuration options fro=
m an=0D
+**EDK II Platform Description (DSC)** file or **a Boot Settings File (BSF)=
** file.=0D
+=0D
+It generates a **YAML file** that can be used by the **Config Editor** to =
provide=0D
+a graphical user interface for manipulating settings in the UPD regions.=0D
+=0D
+The following sections explain the usage of this script.=0D
+=0D
+## 1. FspDscBsf2Yaml.py DscFile YamlFile=0D
+=0D
+The **DscFile** option is an input DSC file.=0D
+=0D
+The **YamlFile** option is an output YAML file.=0D
+=0D
+The script takes the FSP DSC file consisting BSF syntax and generates a YA=
ML=0D
+output file describing the boot settings.=0D
+=0D
+## 2. FspDscBsf2Yaml.py BsfFile YamlFile=0D
+=0D
+The **BsfFile** option is an input BSF file.=0D
+=0D
+The **YamlFile** option is an output YAML file.=0D
+=0D
+The script generates a YAML output file from a BSF file. The BSF file=0D
+can be generated using GenCfgOpt tool.=0D
--=20
2.28.0.windows.1


Re: reg: IPv6 ISCSI Boot with Windows 2019

Sivaraman Nainar
 

Hello Maciej:

 

The issue can be seen in edk2-stable201911 onwards. Haven’t  tested the earlier versions.

 

-Siva

From: Rabeda, Maciej [mailto:maciej.rabeda@...]
Sent: Tuesday, February 2, 2021 4:57 PM
To: devel@edk2.groups.io; Sivaraman Nainar
Cc: Santhosh Kumar V
Subject: Re: [edk2-devel] reg: IPv6 ISCSI Boot with Windows 2019

 

Hi Nainar,

Could you try to bisect the issue using older EDKII releases to see whether it reproduces there?

Thanks,
Maciej

On 01-Feb-21 12:57, Sivaraman Nainar wrote:

Hello Maciej:

 

Do we have any update on this Inquiry. IS this need to be checked in Network Pkg or we need to reach Microsoft.

 

The issue happening only with Windows OS especially 2019.

 

Thanks

Siva

From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of Sivaraman Nainar
Sent: Monday, January 4, 2021 9:03 AM
To: devel@edk2.groups.io
Cc: Rabeda, Maciej; Santhosh Kumar V
Subject: [edk2-devel] reg: IPv6 ISCSI Boot with Windows 2019

 

Hello all:

 

When IPv6 based ISCSI boot performed with Windows 2019 as OS we are seeing the below error during Windows boots.  Out of 10  times 1 time it boots properly. Failure rate is 9/10.

 

Does anyone met this issue, Wth IPv4 based boot it always boots to OS.

 

 

-Siva

This e-mail is intended for the use of the addressee only and may contain privileged, confidential, or proprietary information that is exempt from disclosure under law. If you have received this message in error, please inform us promptly by reply e-mail, then delete the e-mail and destroy any printed copy. Thank you.

 


Re: reg: IPv6 ISCSI Boot with Windows 2019

Maciej Rabeda
 

Hi Nainar,

Could you try to bisect the issue using older EDKII releases to see whether it reproduces there?

Thanks,
Maciej

On 01-Feb-21 12:57, Sivaraman Nainar wrote:

Hello Maciej:

 

Do we have any update on this Inquiry. IS this need to be checked in Network Pkg or we need to reach Microsoft.

 

The issue happening only with Windows OS especially 2019.

 

Thanks

Siva

From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of Sivaraman Nainar
Sent: Monday, January 4, 2021 9:03 AM
To: devel@edk2.groups.io
Cc: Rabeda, Maciej; Santhosh Kumar V
Subject: [edk2-devel] reg: IPv6 ISCSI Boot with Windows 2019

 

Hello all:

 

When IPv6 based ISCSI boot performed with Windows 2019 as OS we are seeing the below error during Windows boots.  Out of 10  times 1 time it boots properly. Failure rate is 9/10.

 

Does anyone met this issue, Wth IPv4 based boot it always boots to OS.

 

 

-Siva

This e-mail is intended for the use of the addressee only and may contain privileged, confidential, or proprietary information that is exempt from disclosure under law. If you have received this message in error, please inform us promptly by reply e-mail, then delete the e-mail and destroy any printed copy. Thank you.



Re: [PATCH edk2-platforms v3 1/2] Drivers/OpTeeRpmb: Add an OP-TEE backed RPMB driver

Sami Mujawar
 

Hi Ilias,

Please see my response inline marked [SAMI].

Regards,

Sami Mujawar

-----Original Message-----
From: Ilias Apalodimas <ilias.apalodimas@...>
Sent: 01 February 2021 02:01 PM
To: Sami Mujawar <Sami.Mujawar@...>
Cc: Sughosh Ganu <sughosh.ganu@...>; devel@edk2.groups.io; Ard Biesheuvel <Ard.Biesheuvel@...>; Leif Lindholm <leif@...>; Sahil Malhotra <sahil.malhotra@...>
Subject: Re: [PATCH edk2-platforms v3 1/2] Drivers/OpTeeRpmb: Add an OP-TEE backed RPMB driver

Hi Sami,


[...]
+STATIC
+EFI_STATUS
+ReadWriteRpmb (
+ UINTN SvcAct,
+ UINTN Addr,
+ UINTN NumBytes,
+ UINTN Offset
+ )
+{
+ ARM_SVC_ARGS SvcArgs;
+ EFI_STATUS Status;
+
+ ZeroMem (&SvcArgs, sizeof (SvcArgs));
+
+ SvcArgs.Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ_AARCH64;
+ SvcArgs.Arg1 = storage_id;
+ SvcArgs.Arg2 = 0;
+ SvcArgs.Arg3 = SvcAct;
+ SvcArgs.Arg4 = Addr;
+ SvcArgs.Arg5 = NumBytes;
+ SvcArgs.Arg6 = Offset;
+
+ ArmCallSvc (&SvcArgs);
+ if (SvcArgs.Arg3) {
+ DEBUG ((DEBUG_ERROR, "%a: Svc Call 0x%08x Addr: 0x%08x len: 0x%x Offset: 0x%x failed with 0x%x\n",
+ __func__, SvcAct, Addr, NumBytes, Offset, SvcArgs.Arg3));
+ }
+
+ switch (SvcArgs.Arg3) {
+ case ARM_SVC_SPM_RET_SUCCESS:
+ Status = EFI_SUCCESS;
+ break;
+
+ case ARM_SVC_SPM_RET_NOT_SUPPORTED:
+ Status = EFI_UNSUPPORTED;
+ break;
+
+ case ARM_SVC_SPM_RET_INVALID_PARAMS:
+ Status = EFI_INVALID_PARAMETER;
+ break;
+
+ case ARM_SVC_SPM_RET_DENIED:
+ Status = EFI_ACCESS_DENIED;
+ break;
+
+ case ARM_SVC_SPM_RET_NO_MEMORY:
+ Status = EFI_BAD_BUFFER_SIZE;
+ break;
+
+ default:
+ Status = EFI_ACCESS_DENIED;
+ }
[SAMI] Should the error handling here be updated similar to the FF-A StandaloneMmPkg patches?
[/SAMI]
I actually picked up the error handling from the previous non-FFA code.
I'll check what's on Sughosh latest patches and fix it if there are
any differences.
Looking at it again EFI_BAD_BUFFER_SIZE can change to indicate out of
memory properly anyway.
Had another look at this. This seems fine if I just change
EFI_BAD_BUFFER_SIZE -> EFI OUT_OF_RESOURCES because OP-TEE is only
using these errors from FFA. Eventually the OP-TEE code that launches
StMM today, will move to FFA and become a separate SP, so that will
naturally be handled once that's done. I don't see a point of adding
unused error cases.

[SAMI] Referring to the FFA specification, DEN0077A, v1.0, section 10.2 FFA_MSG_SEND_DIRECT_REQ and Table 10.8: FFA_ERROR encoding, I think the
error codes being handled above would be returned in SvcArgs.Arg2.
The message flow would be as follows:
- Caller sends FFA_MSG_SEND_DIRECT_REQ to the target endpoint.
- if the message does not reach the target endpoint, an error code from Table 10.8 may be returned in w2 (i.e. SvcArgs.Arg2)
- If the message reaches the target endpoint, then callee shall invoke one of the following interfaces:
* FFA_MSG_SEND_DIRECT_RESP
* FFA_INTERRUPT
* FFA_SUCCESS
This would mean that if the callee responds with FFA_MSG_SEND_DIRECT_RESP, the callee returned error/status code shall be in w/x3-w/x7 (which I think in this case may be in SvcArgs.Arg3).
[/SAMI]

Regards
/Ilias


[PATCH] UefiPayloadPkg/PlatformBootManager: Connect console after EndOfDxe

Patrick Rudolph
 

Currently the console is connected before EndOfDxe causing OptionsROMs
to be loaded, but their drivers aren't used and thus no GOP is installed.

To make use of 3rdparty OptionROMs connect the console after EndOfDxe.

Tested on Intel CFL board using Nvidia Quadro GPU.

Signed-off-by: Patrick Rudolph <patrick.rudolph@...>
---
UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c | 4 ++=
--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootMana=
ger.c b/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c
index c5c6af0abc..7fa3a048b7 100644
--- a/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c
+++ b/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c
@@ -157,8 +157,6 @@ PlatformBootManagerBeforeConsole (
EFI_INPUT_KEY Down;=0D
EFI_BOOT_MANAGER_LOAD_OPTION BootOption;=0D
=0D
- PlatformConsoleInit ();=0D
-=0D
//=0D
// Register ENTER as CONTINUE key=0D
//=0D
@@ -192,6 +190,8 @@ PlatformBootManagerBeforeConsole (
// Dispatch deferred images after EndOfDxe event and ReadyToLock install=
ation.=0D
//=0D
EfiBootManagerDispatchDeferredImages ();=0D
+=0D
+ PlatformConsoleInit ();=0D
}=0D
=0D
/**=0D
--=20
2.26.2


Re: [PATCH] MdeModulePkg/PciBusDxe: Fix a bug in ProcessOptionRomLight

Wu, Hao A
 

-----Original Message-----
From: Ni, Ray <ray.ni@...>
Sent: Friday, January 29, 2021 5:01 PM
To: Park, Aiden <aiden.park@...>; Wu, Hao A <hao.a.wu@...>;
devel@edk2.groups.io
Cc: Ma, Maurice <maurice.ma@...>; Dong, Guo <guo.dong@...>
Subject: RE: [PATCH] MdeModulePkg/PciBusDxe: Fix a bug in
ProcessOptionRomLight

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

The patch has been pushed via:
PR - https://github.com/tianocore/edk2/pull/1400
Commit - https://github.com/tianocore/edk2/commit/3f90ac3ec03512e2374cd2968c047a7e856a8965

Best Regards,
Hao Wu




-----Original Message-----
From: Park, Aiden <aiden.park@...>
Sent: Friday, January 29, 2021 9:55 AM
To: Wu, Hao A <hao.a.wu@...>; Ni, Ray <ray.ni@...>;
devel@edk2.groups.io
Cc: Ma, Maurice <maurice.ma@...>; Dong, Guo
<guo.dong@...>
Subject: RE: [PATCH] MdeModulePkg/PciBusDxe: Fix a bug in
ProcessOptionRomLight

Hello,

Can you please review this?

-----Original Message-----
From: Park, Aiden <aiden.park@...>
Sent: Wednesday, January 13, 2021 11:01 AM
To: Wu, Hao A <hao.a.wu@...>; Ni, Ray <ray.ni@...>;
devel@edk2.groups.io
Cc: Park, Aiden <aiden.park@...>; Ma, Maurice
<maurice.ma@...>; Dong, Guo <guo.dong@...>
Subject: [PATCH] MdeModulePkg/PciBusDxe: Fix a bug in
ProcessOptionRomLight

From: Aiden Park <aiden.park@...>

The ProcessOptionRomLight() assumes that OpRom has already been
processed in the previous full enumeration and updates
AllOpRomProcessed flag to TRUE by default. However, this may not be
applicable with other pre-stage boot firmwares.

This will update AllOpRomProcessed flag properly by checking
PciRomGetImageMapping().

Signed-off-by: Aiden Park <aiden.park@...>
---
MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
b/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
index 1b64924b7b..e8337e865e 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
@@ -1168,12 +1168,7 @@ ProcessOptionRomLight (
ProcessOptionRomLight (Temp);
}

- PciRomGetImageMapping (Temp);
-
- //
- // The OpRom has already been processed in the first round
- //
- Temp->AllOpRomProcessed = TRUE;
+ Temp->AllOpRomProcessed = PciRomGetImageMapping (Temp);

CurrentLink = CurrentLink->ForwardLink;
}
--
2.20.1
Best Regards,
Aiden


Re: [PATCH v6 1/9] OvmfPkg/CpuHotplugSmm: refactor hotplug logic

Ankur Arora
 

On 2021-01-29 5:15 p.m., Laszlo Ersek wrote:
On 01/29/21 01:59, Ankur Arora wrote:
Refactor CpuHotplugMmi() to pull out the CPU hotplug logic into
ProcessHotAddedCpus(). This is in preparation for supporting CPU
hot-unplug.

Cc: Laszlo Ersek <lersek@...>
Cc: Jordan Justen <jordan.l.justen@...>
Cc: Ard Biesheuvel <ard.biesheuvel@...>
Cc: Igor Mammedov <imammedo@...>
Cc: Boris Ostrovsky <boris.ostrovsky@...>
Cc: Aaron Young <aaron.young@...>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3132
Signed-off-by: Ankur Arora <ankur.a.arora@...>
---

Notes:
> + if (EFI_ERROR(Status)) {
> + goto Fatal;
> }
(13) Without having seen the rest of the patches, I think this error
check should be nested under the same (PluggedCount > 0) condition; in
other words, I think it only makes sense to check Status after we
actually call ProcessHotAddedCpus().
Addresses all comments from v5, except for this one, since the (lack) of
nesting makes more sense after patch 4, "OvmfPkg/CpuHotplugSmm: introduce
UnplugCpus()".

OvmfPkg/CpuHotplugSmm/CpuHotplug.c | 214 ++++++++++++++++++++++---------------
1 file changed, 129 insertions(+), 85 deletions(-)

diff --git a/OvmfPkg/CpuHotplugSmm/CpuHotplug.c b/OvmfPkg/CpuHotplugSmm/CpuHotplug.c
index cfe698ed2b5e..05b1f8cb63a6 100644
--- a/OvmfPkg/CpuHotplugSmm/CpuHotplug.c
+++ b/OvmfPkg/CpuHotplugSmm/CpuHotplug.c
@@ -62,6 +62,130 @@ STATIC UINT32 mPostSmmPenAddress;
//
STATIC EFI_HANDLE mDispatchHandle;
+/**
+ Process CPUs that have been hot-added, per QemuCpuhpCollectApicIds().
+
+ For each such CPU, relocate the SMBASE, and report the CPU to PiSmmCpuDxeSmm
+ via EFI_SMM_CPU_SERVICE_PROTOCOL. If the supposedly hot-added CPU is already
+ known, skip it silently.
+
+ @param[in] PluggedApicIds The APIC IDs of the CPUs that have been
+ hot-plugged.
+
+ @param[in] PluggedCount The number of filled-in APIC IDs in
+ PluggedApicIds.
+
+ @retval EFI_SUCCESS CPUs corresponding to all the APIC IDs are
+ populated.
+
+ @retval EFI_OUT_OF_RESOURCES Out of APIC ID space in "mCpuHotPlugData".
+
+ @return Error codes propagated from SmbaseRelocate()
+ and mMmCpuService->AddProcessor().
+
+**/
+STATIC
+EFI_STATUS
+ProcessHotAddedCpus (
+ IN APIC_ID *PluggedApicIds,
+ IN UINT32 PluggedCount
+ )
+{
+ EFI_STATUS Status;
+ UINT32 PluggedIdx;
+ UINT32 NewSlot;
+
+ //
+ // The Post-SMM Pen need not be reinstalled multiple times within a single
+ // root MMI handling. Even reinstalling once per root MMI is only prudence;
+ // in theory installing the pen in the driver's entry point function should
+ // suffice.
+ //
+ SmbaseReinstallPostSmmPen (mPostSmmPenAddress);
+
+ PluggedIdx = 0;
+ NewSlot = 0;
+ while (PluggedIdx < PluggedCount) {
+ APIC_ID NewApicId;
+ UINT32 CheckSlot;
+ UINTN NewProcessorNumberByProtocol;
+
+ NewApicId = PluggedApicIds[PluggedIdx];
+
+ //
+ // Check if the supposedly hot-added CPU is already known to us.
+ //
+ for (CheckSlot = 0;
+ CheckSlot < mCpuHotPlugData->ArrayLength;
+ CheckSlot++) {
+ if (mCpuHotPlugData->ApicId[CheckSlot] == NewApicId) {
+ break;
+ }
+ }
+ if (CheckSlot < mCpuHotPlugData->ArrayLength) {
+ DEBUG ((DEBUG_VERBOSE, "%a: APIC ID " FMT_APIC_ID " was hot-plugged "
+ "before; ignoring it\n", __FUNCTION__, NewApicId));
+ PluggedIdx++;
+ continue;
+ }
+
+ //
+ // Find the first empty slot in CPU_HOT_PLUG_DATA.
+ //
+ while (NewSlot < mCpuHotPlugData->ArrayLength &&
+ mCpuHotPlugData->ApicId[NewSlot] != MAX_UINT64) {
+ NewSlot++;
+ }
+ if (NewSlot == mCpuHotPlugData->ArrayLength) {
+ DEBUG ((DEBUG_ERROR, "%a: no room for APIC ID " FMT_APIC_ID "\n",
+ __FUNCTION__, NewApicId));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Store the APIC ID of the new processor to the slot.
+ //
+ mCpuHotPlugData->ApicId[NewSlot] = NewApicId;
+
+ //
+ // Relocate the SMBASE of the new CPU.
+ //
+ Status = SmbaseRelocate (NewApicId, mCpuHotPlugData->SmBase[NewSlot],
+ mPostSmmPenAddress);
+ if (EFI_ERROR (Status)) {
+ goto RevokeNewSlot;
+ }
+
+ //
+ // Add the new CPU with EFI_SMM_CPU_SERVICE_PROTOCOL.
+ //
+ Status = mMmCpuService->AddProcessor (mMmCpuService, NewApicId,
+ &NewProcessorNumberByProtocol);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: AddProcessor(" FMT_APIC_ID "): %r\n",
+ __FUNCTION__, NewApicId, Status));
+ goto RevokeNewSlot;
+ }
+
+ DEBUG ((DEBUG_INFO, "%a: hot-added APIC ID " FMT_APIC_ID ", SMBASE 0x%Lx, "
+ "EFI_SMM_CPU_SERVICE_PROTOCOL assigned number %Lu\n", __FUNCTION__,
+ NewApicId, (UINT64)mCpuHotPlugData->SmBase[NewSlot],
+ (UINT64)NewProcessorNumberByProtocol));
+
+ NewSlot++;
+ PluggedIdx++;
+ }
+
+ //
+ // We've processed this batch of hot-added CPUs.
+ //
+ return EFI_SUCCESS;
+
+RevokeNewSlot:
+ mCpuHotPlugData->ApicId[NewSlot] = MAX_UINT64;
+
+ return Status;
+}
/**
CPU Hotplug MMI handler function.
@@ -122,8 +246,6 @@ CpuHotplugMmi (
UINT8 ApmControl;
UINT32 PluggedCount;
UINT32 ToUnplugCount;
- UINT32 PluggedIdx;
- UINT32 NewSlot;
//
// Assert that we are entering this function due to our root MMI handler
@@ -179,87 +301,12 @@ CpuHotplugMmi (
goto Fatal;
}
- //
- // Process hot-added CPUs.
- //
- // The Post-SMM Pen need not be reinstalled multiple times within a single
- // root MMI handling. Even reinstalling once per root MMI is only prudence;
- // in theory installing the pen in the driver's entry point function should
- // suffice.
- //
- SmbaseReinstallPostSmmPen (mPostSmmPenAddress);
+ if (PluggedCount > 0) {
+ Status = ProcessHotAddedCpus (mPluggedApicIds, PluggedCount);
+ }
- PluggedIdx = 0;
- NewSlot = 0;
- while (PluggedIdx < PluggedCount) {
- APIC_ID NewApicId;
- UINT32 CheckSlot;
- UINTN NewProcessorNumberByProtocol;
-
- NewApicId = mPluggedApicIds[PluggedIdx];
-
- //
- // Check if the supposedly hot-added CPU is already known to us.
- //
- for (CheckSlot = 0;
- CheckSlot < mCpuHotPlugData->ArrayLength;
- CheckSlot++) {
- if (mCpuHotPlugData->ApicId[CheckSlot] == NewApicId) {
- break;
- }
- }
- if (CheckSlot < mCpuHotPlugData->ArrayLength) {
- DEBUG ((DEBUG_VERBOSE, "%a: APIC ID " FMT_APIC_ID " was hot-plugged "
- "before; ignoring it\n", __FUNCTION__, NewApicId));
- PluggedIdx++;
- continue;
- }
-
- //
- // Find the first empty slot in CPU_HOT_PLUG_DATA.
- //
- while (NewSlot < mCpuHotPlugData->ArrayLength &&
- mCpuHotPlugData->ApicId[NewSlot] != MAX_UINT64) {
- NewSlot++;
- }
- if (NewSlot == mCpuHotPlugData->ArrayLength) {
- DEBUG ((DEBUG_ERROR, "%a: no room for APIC ID " FMT_APIC_ID "\n",
- __FUNCTION__, NewApicId));
- goto Fatal;
- }
-
- //
- // Store the APIC ID of the new processor to the slot.
- //
- mCpuHotPlugData->ApicId[NewSlot] = NewApicId;
-
- //
- // Relocate the SMBASE of the new CPU.
- //
- Status = SmbaseRelocate (NewApicId, mCpuHotPlugData->SmBase[NewSlot],
- mPostSmmPenAddress);
- if (EFI_ERROR (Status)) {
- goto RevokeNewSlot;
- }
-
- //
- // Add the new CPU with EFI_SMM_CPU_SERVICE_PROTOCOL.
- //
- Status = mMmCpuService->AddProcessor (mMmCpuService, NewApicId,
- &NewProcessorNumberByProtocol);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a: AddProcessor(" FMT_APIC_ID "): %r\n",
- __FUNCTION__, NewApicId, Status));
- goto RevokeNewSlot;
- }
-
- DEBUG ((DEBUG_INFO, "%a: hot-added APIC ID " FMT_APIC_ID ", SMBASE 0x%Lx, "
- "EFI_SMM_CPU_SERVICE_PROTOCOL assigned number %Lu\n", __FUNCTION__,
- NewApicId, (UINT64)mCpuHotPlugData->SmBase[NewSlot],
- (UINT64)NewProcessorNumberByProtocol));
-
- NewSlot++;
- PluggedIdx++;
+ if (EFI_ERROR(Status)) {
(1) I understand why you skipped point (13) from the previous review,
but you missed point (14) as well -- space character missing after
"EFI_ERROR":
https://edk2.groups.io/g/devel/message/70785
Anyway, in case v7 will not be necessary, I can fix this up myself.
With the space character added:
Reviewed-by: Laszlo Ersek <lersek@...>
Thanks. Will fix in v7 (not quite sure how this one escaped me; my eyes
are too used to not having the additional space, but I did have a
grep command that should have caught this one as well.)

Thanks
Ankur

Thanks
Laszlo

+ goto Fatal;
}
//
@@ -267,9 +314,6 @@ CpuHotplugMmi (
//
return EFI_SUCCESS;
-RevokeNewSlot:
- mCpuHotPlugData->ApicId[NewSlot] = MAX_UINT64;
-
Fatal:
ASSERT (FALSE);
CpuDeadLoop ();


Re: [PATCH v6 5/9] OvmfPkg/CpuHotplugSmm: define CPU_HOT_EJECT_DATA

Ankur Arora
 

On 2021-01-31 8:53 p.m., Laszlo Ersek wrote:
On 01/29/21 01:59, Ankur Arora wrote:
Define CPU_HOT_EJECT_DATA and add PCD PcdCpuHotEjectDataAddress, which
will be used to share CPU ejection state between OvmfPkg/CpuHotPlugSmm
and PiSmmCpuDxeSmm.

Cc: Laszlo Ersek <lersek@...>
Cc: Jordan Justen <jordan.l.justen@...>
Cc: Ard Biesheuvel <ard.biesheuvel@...>
Cc: Igor Mammedov <imammedo@...>
Cc: Boris Ostrovsky <boris.ostrovsky@...>
Cc: Aaron Young <aaron.young@...>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3132
Signed-off-by: Ankur Arora <ankur.a.arora@...>
---
OvmfPkg/OvmfPkg.dec | 10 +++++++++
OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf | 1 +
OvmfPkg/Include/Library/CpuHotEjectData.h | 35 +++++++++++++++++++++++++++++++
3 files changed, 46 insertions(+)
create mode 100644 OvmfPkg/Include/Library/CpuHotEjectData.h

diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 4348bb45c64a..1a2debb821d7 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -106,6 +106,10 @@ [LibraryClasses]
#
XenPlatformLib|Include/Library/XenPlatformLib.h

+ ## @libraryclass Share CPU hot-eject state
+ #
+ CpuHotEjectData|Include/Library/CpuHotEjectData.h
+
[Guids]
gUefiOvmfPkgTokenSpaceGuid = {0x93bb96af, 0xb9f2, 0x4eb8, {0x94, 0x62, 0xe0, 0xba, 0x74, 0x56, 0x42, 0x36}}
gEfiXenInfoGuid = {0xd3b46f3b, 0xd441, 0x1244, {0x9a, 0x12, 0x0, 0x12, 0x27, 0x3f, 0xc1, 0x4d}}
(1) Please drop this hunk -- the [LibraryClasses] section should not be
modified, as we're not introducing a new library class.

@@ -352,6 +356,12 @@ [PcdsDynamic, PcdsDynamicEx]
# This PCD is only accessed if PcdSmmSmramRequire is TRUE (see below).
gUefiOvmfPkgTokenSpaceGuid.PcdQ35SmramAtDefaultSmbase|FALSE|BOOLEAN|0x34

+ ## This PCD adds a communication channel between PiSmmCpuDxeSmm and
+ # CpuHotplugSmm.
(2) I suggest:
## This PCD adds a communication channel between OVMF's SmmCpuFeaturesLib
# instance in PiSmmCpuDxeSmm, and CpuHotplugSmm.

+ #
+ # Only accessed if PcdCpuHotPlugSupport is TRUE
(3) This statement is technically true, but I suggest dropping it. In my
opinion, it is not useful (it's a superfluous statement). Here's why:
- We set the "PcdCpuHotPlugSupport" feature flag to TRUE in the OVMF DSC
files exactly when the SMM_REQUIRE feature test macro is set on the
"build" command line.
- The whole SMM infrastructure is included in the firmware binary
exactly when SMM_REQUIRE is set.
In other words, PcdCpuHotPlugSupport is *equivalent* with
SmmCpuFeaturesLib, PiSmmCpuDxeSmm, and CpuHotplugSmm being included in
the firmware binary.
Given that the first comment already declares the PCD as an info channel
between SmmCpuFeaturesLib (as built into PiSmmCpuDxeSmm) and
CpuHotplugSmm, the second comment adds nothing.
That makes sense.


+ gUefiOvmfPkgTokenSpaceGuid.PcdCpuHotEjectDataAddress|0|UINT64|0x46
+
[PcdsFeatureFlag]
gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation|TRUE|BOOLEAN|0x1c
gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderMmioTranslation|FALSE|BOOLEAN|0x1d
diff --git a/OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf b/OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf
index 04322b0d7855..e08b572ef169 100644
--- a/OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf
+++ b/OvmfPkg/CpuHotplugSmm/CpuHotplugSmm.inf
@@ -54,6 +54,7 @@ [Protocols]

[Pcd]
gUefiCpuPkgTokenSpaceGuid.PcdCpuHotPlugDataAddress ## CONSUMES
+ gUefiOvmfPkgTokenSpaceGuid.PcdCpuHotEjectDataAddress ## CONSUMES
gUefiOvmfPkgTokenSpaceGuid.PcdQ35SmramAtDefaultSmbase ## CONSUMES

[FeaturePcd]
(4) Please move this hunk to patch#7 (subject: "OvmfPkg/CpuHotplugSmm:
add CpuEject()"). That's where CpuHotplugSmm first needs the new PCD.

diff --git a/OvmfPkg/Include/Library/CpuHotEjectData.h b/OvmfPkg/Include/Library/CpuHotEjectData.h
new file mode 100644
index 000000000000..b6fb629a1283
--- /dev/null
+++ b/OvmfPkg/Include/Library/CpuHotEjectData.h
@@ -0,0 +1,35 @@
+/** @file
+ Definition for a CPU hot-eject state sharing structure.
+
(5a) I suggest the following language:
Definition of the CPU_HOT_EJECT_DATA structure, which shares CPU hot-eject
state between OVMF's SmmCpuFeaturesLib instance in PiSmmCpuDxeSmm, and
CpuHotplugSmm.
CPU_HOT_EJECT_DATA is allocated in SMRAM, and pointed-to by
PcdCpuHotEjectDataAddress.
(5b) Please append at least one more sentence to state the condition
when the PCD is *not* NULL.
(6) This new header file should be located at:
OvmfPkg/Include/Pcd/CpuHotEjectData.h
Your explanation below makes sense. OvmfPkg/Include/Library did not
quite seem like the right place but I wasn't sure what would be
better.

Will fix.

please.
The (more or less) general rule is this:
- if you have a macro definition or a structure type that is accessible
through a Pcd, a Protocol, a Guid -- HOB, VenHw() devpath node etc --,
a Library, a Register, etc,
- and the Pcd, Protocol, Guid, Library etc in question is declared in
"WhateverPkg/WhateverPkg.dec",
- then the header file defining the structure or macro should be placed
in the following directory (according to the access type):
WhateverPkg/Include/Pcd/
WhateverPkg/Include/Protocol/
WhateverPkg/Include/Guid/
WhateverPkg/Include/Library/
WhateverPkg/Include/Register/
Admittedly, while this rule is universally honored in edk2 in the
Protocol, Guid, and Library cases, the Register case is somewhat less
frequently followed, and the Pcd case is almost nonexistent. For
example, "UefiCpuPkg/Include/CpuHotPlugData.h" itself does not follow
the rule (no "Pcd" subdir). However, there are examples that do follow
the rule:
CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h
RedfishPkg/Include/Pcd/RestExServiceDevicePath.h

+ Copyright (C) 2021, Oracle Corporation.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_HOT_EJECT_DATA_H_
+#define _CPU_HOT_EJECT_DATA_H_
(7) Please use the following guard macro:
CPU_HOT_EJECT_DATA_H_
(i.e., please drop the leading underscore).
Although the leading underscore is widely used in edk2, in include guard
macros, it's a bad practice (it creates identifiers that are reserved by
the C standard), so we should not introduce more of it.

+
+typedef
+VOID
+(EFIAPI *CPU_HOT_EJECT_FN)(
(8) Please replace _FN with _HANDLER or _FUNCTION.
In edk2, we tend to avoid abbreviations. (Yes, the practice has not
entirely been consistent, and sometimes it's actually *annoying* that
our type names are too long. But that's what we got.)
... _HANDLER would be better, as you call the related field "Handler" in
the structure.
(9) Missing space character before the last parenthesis on the line.
(10) Please add a leading comment block on this function prototype.
(Well, yes, I realize it is technically a *pointer* type, but still.)
This is not just a formality; I'd really like the "ProcessorNum"
parameter to be described, for example its relationship with the
"ProcessorNumber" parameter of EFI_SMM_CPU_SERVICE_PROTOCOL member
functions, and/or the "CPU_HOT_PLUG_DATA.ApicId" array.

+ IN UINTN ProcessorNum
+ );
+
+#define CPU_EJECT_INVALID (MAX_UINT64)
+#define CPU_EJECT_WORKER (MAX_UINT64-1)
(11a) If these are meant as special values for the "ApicIdMap" array,
then I'd suggest something like:
CPU_EJECT_APIC_ID_INVALID
CPU_EJECT_APIC_ID_WORKER
(11b) Can you add a single-sentence comment to each macro? (Observe the
comment style while at it, please.)

+
+#define CPU_HOT_EJECT_DATA_REVISION_1 0x00000001
+
+typedef struct {
+ UINT32 Revision; // Used for version identification of
+ // this structure
(12) Please drop both the "CPU_HOT_EJECT_DATA_REVISION_1" macro and the
"Revision" field.
The "CPU_HOT_PLUG_DATA" structure, from
"UefiCpuPkg/Include/CpuHotPlugData.h", is different. That structure is
versioned because it establishes a communication channel between a core
module (PiSmmCpuDxeSmm) and a platform module (such as
OvmfPkg/CpuHotplugSmm); what's more, those modules could even be built
separately, and be available in binary-only form.
(Side note: we ignore "CPU_HOT_PLUG_DATA.Revision" in
"OvmfPkg/CpuHotplugSmm" because the OVMF platforms exist in the exact
same repository as PiSmmCpuDxeSmm, so we can keep them in sync. This is
BTW one reason why I absolutely want OVMF to live in the core edk2
repository. Anyway, digression ends.)
However, the same versioning idea (or requirement) does not hold for the
present use case. The new communication channel is between:
- OVMF's SmmCpuFeaturesLib instance in PiSmmCpuDxeSmm,
- and CpuHotplugSmm.
Both of those are OVMF platform modules, and we never build one without
building the other. (Put differently, we never build PiSmmCpuDxeSmm and
CpuHotplugSmm separately, for any particular OVMF binary.)
Thus, the "Revision" field is useless.
Agreed. I was unsure about adding this field -- but wasn't sure if there
might be situations when CpuHotplugSmm and PiSmmCpuDxeSmm might come
separately or not.

Thanks for clarifying it.


+ UINT32 ArrayLength; // Entries in the ApicIdMap array
+
+ UINT64 *ApicIdMap; // Pointer to CpuIndex->ApicId map for
+ // pending hot-ejects
(13a) "CpuIndex" is yet another name here; if you mean
"ProcessorNum[ber]" -- see point (10) above --, then please use that
word.
I did. Will fix.

(13b) Also, the "->" arrow is a bit confusing (is "CpuIndex" a
pointer???), so please either use " -> " (spaces on both sides) or write
"ProcessorNumber-to-ApicId".

+ CPU_HOT_EJECT_FN Handler; // Handler to do the CPU ejection
+
+ UINT64 Reserved;
(14) Please drop the "Reserved" field as well, with the justification
given in (12).

+} CPU_HOT_EJECT_DATA;
+
+#endif /* _CPU_HOT_EJECT_DATA_H_ */
(15) Comment style is wrong; should be //.
(I admit that you may find many examples for the wrong comment style,
near such "#endif" directives, under OvmfPkg/Include; sorry about that.)
(16) Please drop the leading underscore here too.
Will fix and acking all the other comments that I did not explicitly
address as well.

Thanks
Ankur

I plan to continue the review either today, or sometime later this week.
Thanks!
Laszlo


Re: [PATCH v6 3/9] OvmfPkg/CpuHotplugSmm: add Qemu Cpu Status helper

Ankur Arora
 

On 2021-01-29 6:36 p.m., Laszlo Ersek wrote:
On 01/29/21 01:59, Ankur Arora wrote:
Add QemuCpuhpWriteCpuStatus() which will be used to update the QEMU
CPU status register. On error, it hangs in a similar fashion as
other helper functions.

Cc: Laszlo Ersek <lersek@...>
Cc: Jordan Justen <jordan.l.justen@...>
Cc: Ard Biesheuvel <ard.biesheuvel@...>
Cc: Igor Mammedov <imammedo@...>
Cc: Boris Ostrovsky <boris.ostrovsky@...>
Cc: Aaron Young <aaron.young@...>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3132
Signed-off-by: Ankur Arora <ankur.a.arora@...>
---
OvmfPkg/CpuHotplugSmm/QemuCpuhp.h | 6 ++++++
OvmfPkg/CpuHotplugSmm/QemuCpuhp.c | 22 ++++++++++++++++++++++
2 files changed, 28 insertions(+)

diff --git a/OvmfPkg/CpuHotplugSmm/QemuCpuhp.h b/OvmfPkg/CpuHotplugSmm/QemuCpuhp.h
index 8adaa0ad91f0..804809846890 100644
--- a/OvmfPkg/CpuHotplugSmm/QemuCpuhp.h
+++ b/OvmfPkg/CpuHotplugSmm/QemuCpuhp.h
@@ -30,6 +30,12 @@ QemuCpuhpReadCpuStatus (
IN CONST EFI_MM_CPU_IO_PROTOCOL *MmCpuIo
);
+VOID
+QemuCpuhpWriteCpuStatus (
+ IN CONST EFI_MM_CPU_IO_PROTOCOL *MmCpuIo,
+ IN UINT8 CpuStatus
+ );
+
UINT32
QemuCpuhpReadCommandData (
IN CONST EFI_MM_CPU_IO_PROTOCOL *MmCpuIo
diff --git a/OvmfPkg/CpuHotplugSmm/QemuCpuhp.c b/OvmfPkg/CpuHotplugSmm/QemuCpuhp.c
index f871e50c377b..ed44264de934 100644
--- a/OvmfPkg/CpuHotplugSmm/QemuCpuhp.c
+++ b/OvmfPkg/CpuHotplugSmm/QemuCpuhp.c
@@ -67,6 +67,28 @@ QemuCpuhpReadCpuStatus (
return CpuStatus;
}
+VOID
+QemuCpuhpWriteCpuStatus (
+ IN CONST EFI_MM_CPU_IO_PROTOCOL *MmCpuIo,
+ IN UINT8 CpuStatus
+ )
+{
+ EFI_STATUS Status;
+
+ Status = MmCpuIo->Io.Write (
+ MmCpuIo,
+ MM_IO_UINT8,
+ ICH9_CPU_HOTPLUG_BASE + QEMU_CPUHP_R_CPU_STAT,
+ 1,
+ &CpuStatus
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: %r\n", __FUNCTION__, Status));
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+ }
+}
+
UINT32
QemuCpuhpReadCommandData (
IN CONST EFI_MM_CPU_IO_PROTOCOL *MmCpuIo
The code is fine, but please move the new function (both declaration and
definition) between QemuCpuhpWriteCpuSelector() and QemuCpuhpWriteCommand().
Reason: the pre-patch order of the functions matches the order of the
register descriptions in QEMU's "docs/specs/acpi_cpu_hotplug.txt".
There, we first have a section called "read access", then another called
"write access". And in each section, registers are listed in increasing
offset order, within the hotplug register block.
Will fix.

Thanks
Ankur

Thanks!
Laszlo


Re: [PATCH v6 2/9] OvmfPkg/CpuHotplugSmm: collect hot-unplug events

Ankur Arora
 

On 2021-01-29 6:18 p.m., Laszlo Ersek wrote:
On 01/29/21 01:59, Ankur Arora wrote:
Process fw_remove events in QemuCpuhpCollectApicIds() and collect
corresponding APIC IDs for CPUs that are being hot-unplugged.

In addition, we now ignore CPUs which only have remove set. These
CPUs haven't been processed by OSPM yet.

This is based on the QEMU hot-unplug protocol documented here:
https://lore.kernel.org/qemu-devel/20201204170939.1815522-3-imammedo@redhat.com/

Also define QEMU_CPUHP_STAT_EJECTED while we are at it.
(1) Please move the addition of QEMU_CPUHP_STAT_EJECTED to patch 8
("OvmfPkg/CpuHotplugSmm: add worker to do CPU ejection"), where you
first use it.


Cc: Laszlo Ersek <lersek@...>
Cc: Jordan Justen <jordan.l.justen@...>
Cc: Ard Biesheuvel <ard.biesheuvel@...>
Cc: Igor Mammedov <imammedo@...>
Cc: Boris Ostrovsky <boris.ostrovsky@...>
Cc: Aaron Young <aaron.young@...>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3132
Signed-off-by: Ankur Arora <ankur.a.arora@...>
---

Notes:
I'm treating events (insert=1, fw_remove=1) below as invalid (return
EFI_PROTOCOL_ERROR, which ends up as an assert), but I'm not sure
that is correct:

if ((CpuStatus & QEMU_CPUHP_STAT_INSERT) != 0) {
//
// The "insert" event guarantees the "enabled" status; plus it excludes
- // the "remove" event.
+ // the "fw_remove" event.
//
if ((CpuStatus & QEMU_CPUHP_STAT_ENABLED) == 0 ||
- (CpuStatus & QEMU_CPUHP_STAT_REMOVE) != 0) {
+ (CpuStatus & QEMU_CPUHP_STAT_FW_REMOVE) != 0) {
DEBUG ((DEBUG_ERROR, "%a: CurrentSelector=%u CpuStatus=0x%x: "
"inconsistent CPU status\n", __FUNCTION__, CurrentSelector,
CpuStatus));

QEMU's handling in cpu_hotplug_rd() can return both of these:

cpu_hotplug_rd() {
...
case ACPI_CPU_FLAGS_OFFSET_RW: /* pack and return is_* fields */
val |= cdev->cpu ? 1 : 0;
val |= cdev->is_inserting ? 2 : 0;
val |= cdev->is_removing ? 4 : 0;
val |= cdev->fw_remove ? 16 : 0;
...
}
and I don't see any code that treats is_inserting and is_removing as
exclusive.

One specific case where this looks it might be a problem is if the user
unplugs a CPU and right after that plugs it.

As part of the unplug handling, the ACPI AML would, in the scan loop,
asynchronously trigger the notify, which would do the OS unplug, set
"fw_remove" and then call the SMI_CMD.

The subsequent plug could then come and set the "insert" bit.

Assuming what I'm describing could happen, I'm not sure what's the right
handling: QEMU could treat these bits as exclusive and then OVMF could
justifiably treat it as a protocol error?
I'm OK with the related part of your patch (i.e., returning
EFI_PROTOCOL_ERROR for (insert=1, fw_remove=1)).


OvmfPkg/Include/IndustryStandard/QemuCpuHotplug.h | 2 ++
OvmfPkg/CpuHotplugSmm/QemuCpuhp.c | 29 +++++++++++++++++++----
2 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/OvmfPkg/Include/IndustryStandard/QemuCpuHotplug.h b/OvmfPkg/Include/IndustryStandard/QemuCpuHotplug.h
index a34a6d3fae61..692e3072598c 100644
--- a/OvmfPkg/Include/IndustryStandard/QemuCpuHotplug.h
+++ b/OvmfPkg/Include/IndustryStandard/QemuCpuHotplug.h
@@ -34,6 +34,8 @@
#define QEMU_CPUHP_STAT_ENABLED BIT0
#define QEMU_CPUHP_STAT_INSERT BIT1
#define QEMU_CPUHP_STAT_REMOVE BIT2
+#define QEMU_CPUHP_STAT_EJECTED BIT3
+#define QEMU_CPUHP_STAT_FW_REMOVE BIT4

#define QEMU_CPUHP_RW_CMD_DATA 0x8

diff --git a/OvmfPkg/CpuHotplugSmm/QemuCpuhp.c b/OvmfPkg/CpuHotplugSmm/QemuCpuhp.c
index 8d4a6693c8d6..f871e50c377b 100644
--- a/OvmfPkg/CpuHotplugSmm/QemuCpuhp.c
+++ b/OvmfPkg/CpuHotplugSmm/QemuCpuhp.c
@@ -245,10 +245,10 @@ QemuCpuhpCollectApicIds (
if ((CpuStatus & QEMU_CPUHP_STAT_INSERT) != 0) {
//
// The "insert" event guarantees the "enabled" status; plus it excludes
- // the "remove" event.
+ // the "fw_remove" event.
//
if ((CpuStatus & QEMU_CPUHP_STAT_ENABLED) == 0 ||
- (CpuStatus & QEMU_CPUHP_STAT_REMOVE) != 0) {
+ (CpuStatus & QEMU_CPUHP_STAT_FW_REMOVE) != 0) {
DEBUG ((DEBUG_ERROR, "%a: CurrentSelector=%u CpuStatus=0x%x: "
"inconsistent CPU status\n", __FUNCTION__, CurrentSelector,
CpuStatus));
@@ -260,12 +260,31 @@ QemuCpuhpCollectApicIds (

ExtendIds = PluggedApicIds;
ExtendCount = PluggedCount;
- } else if ((CpuStatus & QEMU_CPUHP_STAT_REMOVE) != 0) {
- DEBUG ((DEBUG_VERBOSE, "%a: CurrentSelector=%u: remove\n", __FUNCTION__,
- CurrentSelector));
+ } else if ((CpuStatus & QEMU_CPUHP_STAT_FW_REMOVE) != 0) {
+ //
+ // "fw_remove" event guarantees "enabled".
+ //
+ if ((CpuStatus & QEMU_CPUHP_STAT_ENABLED) == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: CurrentSelector=%u CpuStatus=0x%x: "
+ "inconsistent CPU status\n", __FUNCTION__, CurrentSelector,
+ CpuStatus));
+ return EFI_PROTOCOL_ERROR;
+ }
+
+ DEBUG ((DEBUG_VERBOSE, "%a: CurrentSelector=%u: fw_remove\n",
+ __FUNCTION__, CurrentSelector));

ExtendIds = ToUnplugApicIds;
ExtendCount = ToUnplugCount;
+ } else if ((CpuStatus & QEMU_CPUHP_STAT_REMOVE) != 0) {
+ //
+ // Let the OSPM deal with the "remove" event.
+ //
+ DEBUG ((DEBUG_INFO, "%a: CurrentSelector=%u: remove (ignored)\n",
+ __FUNCTION__, CurrentSelector));
(2) Please downgrade this debug mask from DEBUG_INFO to DEBUG_VERBOSE.
(If you want your OVMF build to emit DEBUG_VERBOSE messages to the log,
you can set PcdDebugPrintErrorLevel to 0x8040004F in the DSC file --
DEBUG_VERBOSE has value 0x00400000.)

+
+ CurrentSelector++;
+ continue;
(3) This change is logically correct; however I request a different
implementation, as I indicated here:
https://lists.gnu.org/archive/html/qemu-devel/2020-11/msg06737.html
msgid: <926113ec-8fa1-7d3b-ff3f-f1eda692e83d@...>
Namely:
(3a) On this branch, please set both "ExtendIds" and "ExtendCount" to
NULL, replacing the currently proposed "CurrentSelector" increment and
the "continue" statement.
(3b) Locate the section of code that starts with the comment "Save the
APIC ID of the CPU with the pending event...", and make it conditional
like this:
ASSERT ((ExtendIds == NULL) == (ExtendCount == NULL));
if (ExtendIds != NULL) {
...
}
(3c) and then simply proceed to the end of the loop body, where we
increment "CurrentSelector" already.
Here's why I'm asing for this: with your proposed v6 patch, the loop
body would receive a "CurrentSelector" increment operation that did not
explain itself. And I'd really like to keep *any* "CurrentSelector"
increment operation explained by the comment that we currently have at
the end of the loop body:
//
// We've processed the CPU with (known) pending events, but we must never
// clear events. Therefore we need to advance past this CPU manually;
// otherwise, QEMU_CPUHP_CMD_GET_PENDING would stick to the currently
// selected CPU.
//
Keeping up that "well-explained" status would require one of two
options:
- copy the comment into the new branch (duplicating the comment) just
before you add the new "CurrentSelector" increment operation, or
- make sure we have just one spot where we increment "CurrentSelector",
and preserve the comment there.
The second option looks much better to me, so that's what I'm asking
for.
If we didn't have that big comment on the increment, your solution would
be just fine, but said comment is really important IMO.
Yeah you are right, that comment is quite useful to keep in mind. Will fix.

Also acking the other review comments here (including the EJECTED -> EJECT
change.)

Thanks
Ankur

Thanks!
Laszlo

} else {
DEBUG ((DEBUG_VERBOSE, "%a: CurrentSelector=%u: no event\n",
__FUNCTION__, CurrentSelector));


回复: [PATCH] MdePkg/Include: Add CET instructions to Nasm.inc

gaoliming
 

Sheng:
Can you check nasm version in ubuntu-18.04 and latest ubuntu OS? Those Oss are used in open CI.

Thanks
Liming

-----邮件原件-----
发件人: Sheng, W <w.sheng@...>
发送时间: 2021年2月2日 11:39
收件人: gaoliming <gaoliming@...>; Kinney, Michael D
<michael.d.kinney@...>; devel@edk2.groups.io
抄送: Liu, Zhiguang <zhiguang.liu@...>; Yao, Jiewen
<jiewen.yao@...>; 'Andrew Fish' <afish@...>; 'Laszlo Ersek'
<lersek@...>; Feng, Roger <roger.feng@...>
主题: RE: [PATCH] MdePkg/Include: Add CET instructions to Nasm.inc

Hi Mike, Liming,
The latest NASM version is version 2.15.05.
The CET instructions is supported since NASM version 2.15.01, it is released at
2020-06-27.
Do you think we need to request everyone to update the NASM tool now?
Or could I still use macros with DB for CET instructions in my patch ?
BR
Sheng Wei

-----Original Message-----
From: gaoliming <gaoliming@...>
Sent: 2021年2月2日 10:44
To: Kinney, Michael D <michael.d.kinney@...>; Sheng, W
<w.sheng@...>; devel@edk2.groups.io
Cc: Liu, Zhiguang <zhiguang.liu@...>; Yao, Jiewen
<jiewen.yao@...>; 'Andrew Fish' <afish@...>; 'Laszlo Ersek'
<lersek@...>
Subject: 回复: [PATCH] MdePkg/Include: Add CET instructions to Nasm.inc

Mike and Sheng:
Linux or Mac OS includes the pre-built nasm. Their nasm version may be
old.
Can you evaluate the impact to update nasm version?

Thanks
Liming
-----邮件原件-----
发件人: Kinney, Michael D <michael.d.kinney@...>
发送时间: 2021年1月30日 1:23
收件人: Sheng, W <w.sheng@...>; devel@edk2.groups.io; Kinney,
Michael D <michael.d.kinney@...>
抄送: Liming Gao <gaoliming@...>; Liu, Zhiguang
<zhiguang.liu@...>; Yao, Jiewen <jiewen.yao@...>
主题: RE: [PATCH] MdePkg/Include: Add CET instructions to Nasm.inc

Sheng,

The following version of the NASM documentation shows support for
these instructions.

https://nasm.us/doc/nasmdocb.html

Do we need to increase the min NASM version requirements for EDK II to
avoid adding macros with DB?

Thanks,

Mike

-----Original Message-----
From: Sheng, W <w.sheng@...>
Sent: Thursday, January 28, 2021 6:35 PM
To: devel@edk2.groups.io
Cc: Kinney, Michael D <michael.d.kinney@...>; Liming Gao
<gaoliming@...>; Liu, Zhiguang
<zhiguang.liu@...>; Yao, Jiewen <jiewen.yao@...>
Subject: [PATCH] MdePkg/Include: Add CET instructions to Nasm.inc

This is to add instruction SAVEPREVSSP, CLRSSBSY and RSTORSSP_RAX in
Nasm,
because these instructions are not supported yet.

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

Signed-off-by: Sheng Wei <w.sheng@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Liming Gao <gaoliming@...>
Cc: Zhiguang Liu <zhiguang.liu@...>
Cc: Jiewen Yao <jiewen.yao@...>
---
MdePkg/Include/Ia32/Nasm.inc | 14 +++++++++++++-
MdePkg/Include/X64/Nasm.inc | 14 +++++++++++++-
2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/MdePkg/Include/Ia32/Nasm.inc
b/MdePkg/Include/Ia32/Nasm.inc
index 31ce861f1e..9c1b7796ea 100644
--- a/MdePkg/Include/Ia32/Nasm.inc
+++ b/MdePkg/Include/Ia32/Nasm.inc
@@ -1,6 +1,6 @@

;-------------------------------------------------------------------
-----------
;
-; Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+; Copyright (c) 2019 - 2021, Intel Corporation. All rights
+reserved.<BR>
; SPDX-License-Identifier: BSD-2-Clause-Patent ; ; Abstract:
@@ -20,3 +20,15 @@
%macro INCSSP_EAX 0
DB 0xF3, 0x0F, 0xAE, 0xE8
%endmacro
+
+%macro SAVEPREVSSP 0
+ DB 0xF3, 0x0F, 0x01, 0xEA
+%endmacro
+
+%macro CLRSSBSY_EAX 0
+ DB 0x67, 0xF3, 0x0F, 0xAE, 0x30 %endmacro
+
+%macro RSTORSSP_EAX 0
+ DB 0x67, 0xF3, 0x0F, 0x01, 0x28 %endmacro
diff --git a/MdePkg/Include/X64/Nasm.inc
b/MdePkg/Include/X64/Nasm.inc
index 42412735ea..c5189982bb 100644
--- a/MdePkg/Include/X64/Nasm.inc
+++ b/MdePkg/Include/X64/Nasm.inc
@@ -1,6 +1,6 @@

;-------------------------------------------------------------------
-----------
;
-; Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+; Copyright (c) 2019 - 2021, Intel Corporation. All rights
+reserved.<BR>
; SPDX-License-Identifier: BSD-2-Clause-Patent ; ; Abstract:
@@ -20,3 +20,15 @@
%macro INCSSP_RAX 0
DB 0xF3, 0x48, 0x0F, 0xAE, 0xE8 %endmacro
+
+%macro SAVEPREVSSP 0
+ DB 0xF3, 0x0F, 0x01, 0xEA
+%endmacro
+
+%macro CLRSSBSY_RAX 0
+ DB 0xF3, 0x0F, 0xAE, 0x30
+%endmacro
+
+%macro RSTORSSP_RAX 0
+ DB 0xF3, 0x0F, 0x01, 0x28
+%endmacro
--
2.16.2.windows.1


Re: [PATCH] MdePkg/Include: Add CET instructions to Nasm.inc

Sheng Wei
 

Hi Mike, Liming,
The latest NASM version is version 2.15.05.
The CET instructions is supported since NASM version 2.15.01, it is released at 2020-06-27.
Do you think we need to request everyone to update the NASM tool now?
Or could I still use macros with DB for CET instructions in my patch ?
BR
Sheng Wei

-----Original Message-----
From: gaoliming <gaoliming@...>
Sent: 2021年2月2日 10:44
To: Kinney, Michael D <michael.d.kinney@...>; Sheng, W
<w.sheng@...>; devel@edk2.groups.io
Cc: Liu, Zhiguang <zhiguang.liu@...>; Yao, Jiewen
<jiewen.yao@...>; 'Andrew Fish' <afish@...>; 'Laszlo Ersek'
<lersek@...>
Subject: 回复: [PATCH] MdePkg/Include: Add CET instructions to Nasm.inc

Mike and Sheng:
Linux or Mac OS includes the pre-built nasm. Their nasm version may be old.
Can you evaluate the impact to update nasm version?

Thanks
Liming
-----邮件原件-----
发件人: Kinney, Michael D <michael.d.kinney@...>
发送时间: 2021年1月30日 1:23
收件人: Sheng, W <w.sheng@...>; devel@edk2.groups.io; Kinney,
Michael D <michael.d.kinney@...>
抄送: Liming Gao <gaoliming@...>; Liu, Zhiguang
<zhiguang.liu@...>; Yao, Jiewen <jiewen.yao@...>
主题: RE: [PATCH] MdePkg/Include: Add CET instructions to Nasm.inc

Sheng,

The following version of the NASM documentation shows support for
these instructions.

https://nasm.us/doc/nasmdocb.html

Do we need to increase the min NASM version requirements for EDK II to
avoid adding macros with DB?

Thanks,

Mike

-----Original Message-----
From: Sheng, W <w.sheng@...>
Sent: Thursday, January 28, 2021 6:35 PM
To: devel@edk2.groups.io
Cc: Kinney, Michael D <michael.d.kinney@...>; Liming Gao
<gaoliming@...>; Liu, Zhiguang
<zhiguang.liu@...>; Yao, Jiewen <jiewen.yao@...>
Subject: [PATCH] MdePkg/Include: Add CET instructions to Nasm.inc

This is to add instruction SAVEPREVSSP, CLRSSBSY and RSTORSSP_RAX in
Nasm,
because these instructions are not supported yet.

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

Signed-off-by: Sheng Wei <w.sheng@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Liming Gao <gaoliming@...>
Cc: Zhiguang Liu <zhiguang.liu@...>
Cc: Jiewen Yao <jiewen.yao@...>
---
MdePkg/Include/Ia32/Nasm.inc | 14 +++++++++++++-
MdePkg/Include/X64/Nasm.inc | 14 +++++++++++++-
2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/MdePkg/Include/Ia32/Nasm.inc
b/MdePkg/Include/Ia32/Nasm.inc
index 31ce861f1e..9c1b7796ea 100644
--- a/MdePkg/Include/Ia32/Nasm.inc
+++ b/MdePkg/Include/Ia32/Nasm.inc
@@ -1,6 +1,6 @@

;-------------------------------------------------------------------
-----------
;
-; Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+; Copyright (c) 2019 - 2021, Intel Corporation. All rights
+reserved.<BR>
; SPDX-License-Identifier: BSD-2-Clause-Patent ; ; Abstract:
@@ -20,3 +20,15 @@
%macro INCSSP_EAX 0
DB 0xF3, 0x0F, 0xAE, 0xE8
%endmacro
+
+%macro SAVEPREVSSP 0
+ DB 0xF3, 0x0F, 0x01, 0xEA
+%endmacro
+
+%macro CLRSSBSY_EAX 0
+ DB 0x67, 0xF3, 0x0F, 0xAE, 0x30 %endmacro
+
+%macro RSTORSSP_EAX 0
+ DB 0x67, 0xF3, 0x0F, 0x01, 0x28 %endmacro
diff --git a/MdePkg/Include/X64/Nasm.inc
b/MdePkg/Include/X64/Nasm.inc
index 42412735ea..c5189982bb 100644
--- a/MdePkg/Include/X64/Nasm.inc
+++ b/MdePkg/Include/X64/Nasm.inc
@@ -1,6 +1,6 @@

;-------------------------------------------------------------------
-----------
;
-; Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+; Copyright (c) 2019 - 2021, Intel Corporation. All rights
+reserved.<BR>
; SPDX-License-Identifier: BSD-2-Clause-Patent ; ; Abstract:
@@ -20,3 +20,15 @@
%macro INCSSP_RAX 0
DB 0xF3, 0x48, 0x0F, 0xAE, 0xE8 %endmacro
+
+%macro SAVEPREVSSP 0
+ DB 0xF3, 0x0F, 0x01, 0xEA
+%endmacro
+
+%macro CLRSSBSY_RAX 0
+ DB 0xF3, 0x0F, 0xAE, 0x30
+%endmacro
+
+%macro RSTORSSP_RAX 0
+ DB 0xF3, 0x0F, 0x01, 0x28
+%endmacro
--
2.16.2.windows.1


回复: [edk2-devel] 回复: [Wiki] Add update notes for incomaptible patches that fix typos in SmBios.h

gaoliming
 

Zhiguang:
Yes. If the information includes structure name SMBIOS_TABLE_TYPE17, it will be better.

For example, SMBIOS_TABLE_TYPE17.FirwareVersion ==> SMBIOS_TABLE_TYPE17.FirmwareVersion

Thanks
Liming

-----邮件原件-----
发件人: bounce+27952+71005+4905953+8761045@groups.io
<bounce+27952+71005+4905953+8761045@groups.io> 代表 Zhiguang Liu
发送时间: 2021年2月1日 14:55
收件人: devel@edk2.groups.io; gaoliming@...
主题: Re: [edk2-devel] 回复: [Wiki] Add update notes for incomaptible
patches that fix typos in SmBios.h

Hi Liming,

The edk2 commits that fixes the typo has been included using the hyper link.
The platforms side's modification doesn't have example to show here.
Do you think it is necessary to list all the typo these commits fixed, like below?
FirwareVersion -> FirmwareVersion
ProcessorManufacture -> ProcessorManufacturer
Processor64BitCapble -> Processor64BitCapable
ProcessorEnhancedVirtulization -> ProcessorEnhancedVirtualization
Processor128bitCapble -> Processor128BitCapable

Thanks
Zhiguang

-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of
gaoliming
Sent: Thursday, January 28, 2021 9:21 AM
To: Liu, Zhiguang <zhiguang.liu@...>; devel@edk2.groups.io
Subject: [edk2-devel] 回复: [Wiki] Add update notes for incomaptible
patches that fix typos in SmBios.h

Zhiguang:
Can you summary the code change in the notes? And, also include the
edk2
commits for the detail.

Thanks
Liming
-----邮件原件-----
发件人: Zhiguang Liu <zhiguang.liu@...>
发送时间: 2021年1月27日 10:09
收件人: devel@edk2.groups.io
抄送: Liming Gao <gaoliming@...>
主题: [Wiki] Add update notes for incomaptible patches that fix typos in
SmBios.h

Cc: Liming Gao <gaoliming@...>
Signed-off-by: Zhiguang Liu <zhiguang.liu@...>
---
EDK-II-Release-Planning.md | 1 +
1 file changed, 1 insertion(+)

diff --git a/EDK-II-Release-Planning.md b/EDK-II-Release-Planning.md
index 336d8d2..bbb5f18 100644
--- a/EDK-II-Release-Planning.md
+++ b/EDK-II-Release-Planning.md
@@ -32,6 +32,7 @@
* If the user has the windows bat script that calls Split in it,it needs to
change to "call Split" because Split will be a bat script but not an
executable
file.
* Shell depends on library class OrderedCollectionLib. Platform DSC
needs
to
configure it in [LibraryClasses]

OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeL
i
b/BaseOrderedCollectionRedBlackTreeLib.inf
+* Some struct fields in SmBios.h have typos and get fixed in these code
change
[0db8](https://github.com/tianocore/edk2/commit/0db89a661f38b10012ff4f
62e1853bfc48efd462),
[bd9d](https://github.com/tianocore/edk2/commit/bd9da7b1da2639fcea8a
1
56fa92a32bbc4209367),
[e157](https://github.com/tianocore/edk2/commit/e157c8f9ed173a390d2c9
d29069a46e9662e0d04). Platform code that uses those fields need
modifications.
* TBD

# edk2-stable202105 tag planning
--
2.30.0.windows.2