A couple of fixes I applied to get Cello in a slightly better shape (although the observed SATA timeout issue requires a change in the core code)
v2: - added patch to disable second SATA controller on Overdrive - use correct port mode mask for overdrive (#3) - update binary AmdModulePkg modules to latest version - add UEFI shell app to reflash to EFI code partition in the NOR - add SMMU enable switch to Cello and Overdrive 1000
Ard Biesheuvel (10): Platforms/AMD/Styx: remove incorrect timer frequency Platforms/AMD/Overdrive: disable second SATA port Platforms/AMD/Styx: set SATA port mode to Gen3 on all ports Platforms/AMD/StyxDtbLoaderLib: disable SMMUs for absent hardware Platform/AMD/Styx: add SMMU override to Cello and Overdrive1000 Platforms/AMD/Cello: add device tree support Platforms/AMD/Cello: reduce core count to 4 Platforms/AMD/Cello: set firmware vendor field to 'LeMaker Cello' Platforms/AMD/Styx/Binary: update binary modules to latest version Platforms/AMD/Styx: add command line flash tool
Platforms/AMD/Styx/Applications/StyxFlashUefi/Scripts/GccBase.lds | 86 ++++++++++++++++++ Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashImage.S | 25 +++++ Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.c | 96 ++++++++++++++++++++ Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf | 53 +++++++++++ Platforms/AMD/Styx/Binary/AmdModulePkg/Gionb/Gionb.efi | Bin 43296 -> 36768 bytes Platforms/AMD/Styx/Binary/AmdModulePkg/Gionb/Gionb.inf | 14 ++- Platforms/AMD/Styx/Binary/AmdModulePkg/Iscp/IscpDxe.efi | Bin 262144 -> 262144 bytes Platforms/AMD/Styx/Binary/AmdModulePkg/Iscp/IscpPei.efi | Bin 10336 -> 6976 bytes Platforms/AMD/Styx/Binary/AmdModulePkg/SnpDxe/SnpDxePort0.efi | Bin 30272 -> 24992 bytes Platforms/AMD/Styx/Binary/AmdModulePkg/SnpDxe/SnpDxePort1.efi | Bin 30272 -> 24992 bytes Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc | 39 ++++++-- Platforms/AMD/Styx/CelloBoard/CelloBoard.fdf | 9 ++ Platforms/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c | 9 +- Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc | 19 ++-- Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc | 20 ++-- 15 files changed, 338 insertions(+), 32 deletions(-) create mode 100644 Platforms/AMD/Styx/Applications/StyxFlashUefi/Scripts/GccBase.lds create mode 100644 Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashImage.S create mode 100644 Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.c create mode 100644 Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf
The ARM generic timer needs to be programmed with the actual frequency of the input clock, but this can only be done from the most privileged execution mode implemented by the hardware. UEFI on AArch64 usually executes in EL2, which is not the most privileged execution mode in most cases, and so the timer driver is set up to deal with this: no attempt is made to program the PCD value PcdArmArchTimerFreqInHz into the frequency register. However, a non-zero PCD value is still treated as an override for the register value, in case the programmed value is known to be incorrect.
However, on the various Styx based platforms, the PCD value is set to an incorrect non-zero value, and so the routines that convert time delays into cycle counts are off by 33% (187.5 MHz vs 250 MHz). This may affect timeouts related to SATA link training, and other low level routines that rely on accurate timekeeping.
So remove the explicit PCD settings, so they default to 0, letting the driver use the programmed value instead.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org --- Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc | 5 ----- Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc | 5 ----- Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc | 5 ----- 3 files changed, 15 deletions(-)
diff --git a/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc b/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc index f068713bf0b8..ddb944d0beb4 100644 --- a/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc +++ b/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc @@ -400,11 +400,6 @@ DEFINE DO_KCS = 0 gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0xE112F000
# - # ARM Architectual Timer Frequency - # - gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|187500000 - - # # Cello has 2 SATA ports on the first controller. # gAmdStyxTokenSpaceGuid.PcdSata0PortCount|2 diff --git a/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc b/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc index b1a7cfd4c4a8..f6d2d37014dd 100644 --- a/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc +++ b/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc @@ -402,11 +402,6 @@ DEFINE DO_KCS = 1 gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0xE112F000
# - # ARM Architectual Timer Frequency - # - gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|187500000 - - # # 2 ports active on Overdrive 1000 # gAmdStyxTokenSpaceGuid.PcdSata0PortCount|2 diff --git a/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc b/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc index 98f5c9452dcd..7ac3ce3760fa 100644 --- a/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc +++ b/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc @@ -409,11 +409,6 @@ DEFINE DO_KCS = 1 gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0xE112F000
# - # ARM Architectual Timer Frequency - # - gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|187500000 - - # # Overdrive B1 has 14 SATA ports across 2 controllers. # gAmdStyxTokenSpaceGuid.PcdSata0PortCount|8
The second SATA port is only available on B1 silicon, but as it turns out, not on /all/ versions of it: the Overdrive 3000 is B1 based as well, but any attempts to use the second SATA controller cause the firmware to crash. So just disable it.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org --- Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc b/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc index 7ac3ce3760fa..9d533149af07 100644 --- a/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc +++ b/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc @@ -409,10 +409,13 @@ DEFINE DO_KCS = 1 gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0xE112F000
# - # Overdrive B1 has 14 SATA ports across 2 controllers. + # AMD's B1 based Overdrive has 14 SATA ports across 2 controllers. However, + # it appears that Softiron's Overdrive 3000, which is also B1 based, does + # not have the second SATA controller enabled, and any attempts to use it + # will crash the firmware. So use the first controller only. # gAmdStyxTokenSpaceGuid.PcdSata0PortCount|8 - gAmdStyxTokenSpaceGuid.PcdSata1PortCount|6 + gAmdStyxTokenSpaceGuid.PcdSata1PortCount|0
# PCIe Support gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xF0000000
Sorry I'm really late to this thread.
On 06/27/2017 09:21 AM, Ard Biesheuvel wrote:
The second SATA port is only available on B1 silicon, but as it turns out, not on /all/ versions of it: the Overdrive 3000 is B1 based as well, but any attempts to use the second SATA controller cause the firmware to crash. So just disable it.
This is not true. The SoftIron OverDrive 3000 has 14 SATA ports that all work. Did someone at SoftIron tell you this?
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org
Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc b/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc index 7ac3ce3760fa..9d533149af07 100644 --- a/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc +++ b/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc @@ -409,10 +409,13 @@ DEFINE DO_KCS = 1 gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0xE112F000 #
- # Overdrive B1 has 14 SATA ports across 2 controllers.
- # AMD's B1 based Overdrive has 14 SATA ports across 2 controllers. However,
- # it appears that Softiron's Overdrive 3000, which is also B1 based, does
- # not have the second SATA controller enabled, and any attempts to use it
- # will crash the firmware. So use the first controller only. # gAmdStyxTokenSpaceGuid.PcdSata0PortCount|8
- gAmdStyxTokenSpaceGuid.PcdSata1PortCount|6
- gAmdStyxTokenSpaceGuid.PcdSata1PortCount|0
# PCIe Support gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xF0000000
On 29 July 2017 at 02:17, Alan Ott alan@softiron.com wrote:
Sorry I'm really late to this thread.
On 06/27/2017 09:21 AM, Ard Biesheuvel wrote:
The second SATA port is only available on B1 silicon, but as it turns out, not on /all/ versions of it: the Overdrive 3000 is B1 based as well, but any attempts to use the second SATA controller cause the firmware to crash. So just disable it.
This is not true. The SoftIron OverDrive 3000 has 14 SATA ports that all work. Did someone at SoftIron tell you this?
Interesting. Do they all work in UEFI as well?
I programmed the open source Overdrive firmware on a SoftIron box at the ARM office (Punit's), and it crashed in UEFI when trying to initialize the second SATA controller. The same code works fine on my non-SoftIron B1 Overdrive, so I wonder what the difference is.
On 07/29/2017 06:23 AM, Ard Biesheuvel wrote:
On 29 July 2017 at 02:17, Alan Ott alan@softiron.com wrote:
Sorry I'm really late to this thread.
On 06/27/2017 09:21 AM, Ard Biesheuvel wrote:
The second SATA port is only available on B1 silicon, but as it turns out, not on /all/ versions of it: the Overdrive 3000 is B1 based as well, but any attempts to use the second SATA controller cause the firmware to crash. So just disable it.
This is not true. The SoftIron OverDrive 3000 has 14 SATA ports that all work. Did someone at SoftIron tell you this?
Interesting. Do they all work in UEFI as well?
Hi Ard,
We use the 2nd controller from Linux extensively.
Regarding use from within UEFI, this obviously doesn't get as much use by us as does using the drives from Linux (since as you might expect we typically boot from the first port), but I just now booted successfully from all 6 drives on the second controller using debug and release builds.
I programmed the open source Overdrive firmware on a SoftIron box at the ARM office (Punit's), and it crashed in UEFI when trying to initialize the second SATA controller. The same code works fine on my non-SoftIron B1 Overdrive, so I wonder what the difference is.
I can't say for sure. If you have a bad unit, we'd be happy to help you with that.
Alan.
On 31 July 2017 at 18:39, Alan Ott alan@softiron.com wrote:
On 07/29/2017 06:23 AM, Ard Biesheuvel wrote:
On 29 July 2017 at 02:17, Alan Ott alan@softiron.com wrote:
Sorry I'm really late to this thread.
On 06/27/2017 09:21 AM, Ard Biesheuvel wrote:
The second SATA port is only available on B1 silicon, but as it turns out, not on /all/ versions of it: the Overdrive 3000 is B1 based as well, but any attempts to use the second SATA controller cause the firmware to crash. So just disable it.
This is not true. The SoftIron OverDrive 3000 has 14 SATA ports that all work. Did someone at SoftIron tell you this?
Interesting. Do they all work in UEFI as well?
Hi Ard,
We use the 2nd controller from Linux extensively.
Regarding use from within UEFI, this obviously doesn't get as much use by us as does using the drives from Linux (since as you might expect we typically boot from the first port), but I just now booted successfully from all 6 drives on the second controller using debug and release builds.
OK, interesting. I had the same experience on my B1, but flashing this one SoftIron 3000 to the open source firmware resulted in the crash I mentioned.
What I don't remember exactly is whether I updated the secure part as well, or only the EDK2 code and var partitions on the SPI flash.
I programmed the open source Overdrive firmware on a SoftIron box at the ARM office (Punit's), and it crashed in UEFI when trying to initialize the second SATA controller. The same code works fine on my non-SoftIron B1 Overdrive, so I wonder what the difference is.
I can't say for sure. If you have a bad unit, we'd be happy to help you with that.
I must admit disabling the second port was also useful in fixing the Gen1/2/3 setting in AmdSataInitLib, given that the PCD in question is 32-bits and so can only describe 8 ports. I suppose it makes sense to get to the bottom of that one first, though. Did you simply revert that change? Or switch to Gen2 or Gen1?
On 07/31/2017 03:30 PM, Ard Biesheuvel wrote:
On 31 July 2017 at 18:39, Alan Ott alan@softiron.com wrote:
On 07/29/2017 06:23 AM, Ard Biesheuvel wrote:
On 29 July 2017 at 02:17, Alan Ott alan@softiron.com wrote:
Sorry I'm really late to this thread.
On 06/27/2017 09:21 AM, Ard Biesheuvel wrote:
The second SATA port is only available on B1 silicon, but as it turns out, not on /all/ versions of it: the Overdrive 3000 is B1 based as well, but any attempts to use the second SATA controller cause the firmware to crash. So just disable it.
This is not true. The SoftIron OverDrive 3000 has 14 SATA ports that all work. Did someone at SoftIron tell you this?
Interesting. Do they all work in UEFI as well?
Hi Ard,
We use the 2nd controller from Linux extensively.
Regarding use from within UEFI, this obviously doesn't get as much use by us as does using the drives from Linux (since as you might expect we typically boot from the first port), but I just now booted successfully from all 6 drives on the second controller using debug and release builds.
OK, interesting. I had the same experience on my B1, but flashing this one SoftIron 3000 to the open source firmware resulted in the crash I mentioned.
What I don't remember exactly is whether I updated the secure part as well, or only the EDK2 code and var partitions on the SPI flash.
I'm building OverdriveBoard.dsc configuration in OpenPlatformPkg and flashing Build/.../STYX_ROM.fd directly onto the SPI flash. I'm not rebuilding the secure part for any of this.
I programmed the open source Overdrive firmware on a SoftIron box at the ARM office (Punit's), and it crashed in UEFI when trying to initialize the second SATA controller. The same code works fine on my non-SoftIron B1 Overdrive, so I wonder what the difference is.
I can't say for sure. If you have a bad unit, we'd be happy to help you with that.
I must admit disabling the second port was also useful in fixing the Gen1/2/3 setting in AmdSataInitLib, given that the PCD in question is 32-bits and so can only describe 8 ports. I suppose it makes sense to get to the bottom of that one first, though.
Are you talking about PcdSataPortMode? That's 16 bits wide, which I think is what you meant (8 ports * 2 bits is 16). We should increase the size to 32.
Did you simply revert that change? Or switch to Gen2 or Gen1?
I didn't change it. It works fine with that change, but only because 0xffff >> n is still 0xffff.
Alan.
On 31 July 2017 at 20:59, Alan Ott alan@softiron.com wrote:
On 07/31/2017 03:30 PM, Ard Biesheuvel wrote:
On 31 July 2017 at 18:39, Alan Ott alan@softiron.com wrote:
On 07/29/2017 06:23 AM, Ard Biesheuvel wrote:
On 29 July 2017 at 02:17, Alan Ott alan@softiron.com wrote:
Sorry I'm really late to this thread.
On 06/27/2017 09:21 AM, Ard Biesheuvel wrote:
The second SATA port is only available on B1 silicon, but as it turns out, not on /all/ versions of it: the Overdrive 3000 is B1 based as well, but any attempts to use the second SATA controller cause the firmware to crash. So just disable it.
This is not true. The SoftIron OverDrive 3000 has 14 SATA ports that all work. Did someone at SoftIron tell you this?
Interesting. Do they all work in UEFI as well?
Hi Ard,
We use the 2nd controller from Linux extensively.
Regarding use from within UEFI, this obviously doesn't get as much use by us as does using the drives from Linux (since as you might expect we typically boot from the first port), but I just now booted successfully from all 6 drives on the second controller using debug and release builds.
OK, interesting. I had the same experience on my B1, but flashing this one SoftIron 3000 to the open source firmware resulted in the crash I mentioned.
What I don't remember exactly is whether I updated the secure part as well, or only the EDK2 code and var partitions on the SPI flash.
I'm building OverdriveBoard.dsc configuration in OpenPlatformPkg and flashing Build/.../STYX_ROM.fd directly onto the SPI flash. I'm not rebuilding the secure part for any of this.
OK. But in my case, I may have flashed the 3000 board with the open source UEFI only, and kept whatever was in the secure partition.
I programmed the open source Overdrive firmware on a SoftIron box at the ARM office (Punit's), and it crashed in UEFI when trying to initialize the second SATA controller. The same code works fine on my non-SoftIron B1 Overdrive, so I wonder what the difference is.
I can't say for sure. If you have a bad unit, we'd be happy to help you with that.
I must admit disabling the second port was also useful in fixing the Gen1/2/3 setting in AmdSataInitLib, given that the PCD in question is 32-bits and so can only describe 8 ports. I suppose it makes sense to get to the bottom of that one first, though.
Are you talking about PcdSataPortMode? That's 16 bits wide, which I think is what you meant (8 ports * 2 bits is 16). We should increase the size to 32.
Indeed.
Did you simply revert that change? Or switch to Gen2 or Gen1?
I didn't change it. It works fine with that change, but only because 0xffff
n is still 0xffff.
Ah ok. But I thought you had identified that change as the source of a problem?
On 07/31/2017 04:01 PM, Ard Biesheuvel wrote:
On 31 July 2017 at 20:59, Alan Ott alan@softiron.com wrote:
On 07/31/2017 03:30 PM, Ard Biesheuvel wrote:
On 31 July 2017 at 18:39, Alan Ott alan@softiron.com wrote:
On 07/29/2017 06:23 AM, Ard Biesheuvel wrote:
On 29 July 2017 at 02:17, Alan Ott alan@softiron.com wrote:
Sorry I'm really late to this thread.
On 06/27/2017 09:21 AM, Ard Biesheuvel wrote: > The second SATA port is only available on B1 silicon, but as it turns > out, not on /all/ versions of it: the Overdrive 3000 is B1 based as > well, > but any attempts to use the second SATA controller cause the firmware > to > crash. So just disable it.
This is not true. The SoftIron OverDrive 3000 has 14 SATA ports that all work. Did someone at SoftIron tell you this?
Interesting. Do they all work in UEFI as well?
Hi Ard,
We use the 2nd controller from Linux extensively.
Regarding use from within UEFI, this obviously doesn't get as much use by us as does using the drives from Linux (since as you might expect we typically boot from the first port), but I just now booted successfully from all 6 drives on the second controller using debug and release builds.
OK, interesting. I had the same experience on my B1, but flashing this one SoftIron 3000 to the open source firmware resulted in the crash I mentioned.
What I don't remember exactly is whether I updated the secure part as well, or only the EDK2 code and var partitions on the SPI flash.
I'm building OverdriveBoard.dsc configuration in OpenPlatformPkg and flashing Build/.../STYX_ROM.fd directly onto the SPI flash. I'm not rebuilding the secure part for any of this.
OK. But in my case, I may have flashed the 3000 board with the open source UEFI only, and kept whatever was in the secure partition.
Ah, I see. I've never done that.
I programmed the open source Overdrive firmware on a SoftIron box at the ARM office (Punit's), and it crashed in UEFI when trying to initialize the second SATA controller. The same code works fine on my non-SoftIron B1 Overdrive, so I wonder what the difference is.
I can't say for sure. If you have a bad unit, we'd be happy to help you with that.
I must admit disabling the second port was also useful in fixing the Gen1/2/3 setting in AmdSataInitLib, given that the PCD in question is 32-bits and so can only describe 8 ports. I suppose it makes sense to get to the bottom of that one first, though.
Are you talking about PcdSataPortMode? That's 16 bits wide, which I think is what you meant (8 ports * 2 bits is 16). We should increase the size to 32.
Indeed.
Did you simply revert that change? Or switch to Gen2 or Gen1?
I didn't change it. It works fine with that change, but only because 0xffff
n is still 0xffff.
Ah ok. But I thought you had identified that change as the source of a problem?
If you're referring to a comment I left on IRC, I reverted dc07fa34c77cdd and 79aafbadadffb6 (effectively) and my boot stopped hanging. I hadn't worked out what the issue was at the time.
What I've determined now is that gAmdStyxTokenSpaceGuid.PcdSata1PortCount must be specified in the .DSC. It can be zero, but if it's not present it appears to default to 8, and the initialization hangs. This causes HEAD to not boot for me. Does HEAD boot for you?
Alan.
On 31 July 2017 at 21:27, Alan Ott alan@softiron.com wrote:
On 07/31/2017 04:01 PM, Ard Biesheuvel wrote:
On 31 July 2017 at 20:59, Alan Ott alan@softiron.com wrote:
On 07/31/2017 03:30 PM, Ard Biesheuvel wrote:
On 31 July 2017 at 18:39, Alan Ott alan@softiron.com wrote:
On 07/29/2017 06:23 AM, Ard Biesheuvel wrote:
On 29 July 2017 at 02:17, Alan Ott alan@softiron.com wrote: > > Sorry I'm really late to this thread. > > On 06/27/2017 09:21 AM, Ard Biesheuvel wrote: >> >> The second SATA port is only available on B1 silicon, but as it >> turns >> out, not on /all/ versions of it: the Overdrive 3000 is B1 based as >> well, >> but any attempts to use the second SATA controller cause the >> firmware >> to >> crash. So just disable it. > > > This is not true. The SoftIron OverDrive 3000 has 14 SATA ports that > all > work. Did someone at SoftIron tell you this? > Interesting. Do they all work in UEFI as well?
Hi Ard,
We use the 2nd controller from Linux extensively.
Regarding use from within UEFI, this obviously doesn't get as much use by us as does using the drives from Linux (since as you might expect we typically boot from the first port), but I just now booted successfully from all 6 drives on the second controller using debug and release builds.
OK, interesting. I had the same experience on my B1, but flashing this one SoftIron 3000 to the open source firmware resulted in the crash I mentioned.
What I don't remember exactly is whether I updated the secure part as well, or only the EDK2 code and var partitions on the SPI flash.
I'm building OverdriveBoard.dsc configuration in OpenPlatformPkg and flashing Build/.../STYX_ROM.fd directly onto the SPI flash. I'm not rebuilding the secure part for any of this.
OK. But in my case, I may have flashed the 3000 board with the open source UEFI only, and kept whatever was in the secure partition.
Ah, I see. I've never done that.
I programmed the open source Overdrive firmware on a SoftIron box at the ARM office (Punit's), and it crashed in UEFI when trying to initialize the second SATA controller. The same code works fine on my non-SoftIron B1 Overdrive, so I wonder what the difference is.
I can't say for sure. If you have a bad unit, we'd be happy to help you with that.
I must admit disabling the second port was also useful in fixing the Gen1/2/3 setting in AmdSataInitLib, given that the PCD in question is 32-bits and so can only describe 8 ports. I suppose it makes sense to get to the bottom of that one first, though.
Are you talking about PcdSataPortMode? That's 16 bits wide, which I think is what you meant (8 ports * 2 bits is 16). We should increase the size to 32.
Indeed.
Did you simply revert that change? Or switch to Gen2 or Gen1?
I didn't change it. It works fine with that change, but only because 0xffff
n is still 0xffff.
Ah ok. But I thought you had identified that change as the source of a problem?
If you're referring to a comment I left on IRC, I reverted dc07fa34c77cdd and 79aafbadadffb6 (effectively) and my boot stopped hanging. I hadn't worked out what the issue was at the time.
What I've determined now is that gAmdStyxTokenSpaceGuid.PcdSata1PortCount must be specified in the .DSC. It can be zero, but if it's not present it appears to default to 8, and the initialization hangs. This causes HEAD to not boot for me. Does HEAD boot for you?
I am currently running OPP 3c4fa409b6b0ba729161fd4ce4d2ab0dfa036422 but against UDK2017 branch (plus a couple of patches) rather than EDK2 HEAD.
The SATA related PCDs consumed by AmdSataInitLib contain a PcdSataPortMode PCD that sets the port mode to all ports. This PCD defaults to zero, while the code in question has no default, i.e., the value 0 is not treated as either 1, 2 or 3, and so the init sequence is not carried out correctly.
While observed SATA link detection issues on CelloBoard appear to be unrelated to this (i.e., this change did not improve the situation), let's set the correct values nonetheless.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org --- Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc | 1 + Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc | 2 ++ Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc b/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc index ddb944d0beb4..d10c0901c811 100644 --- a/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc +++ b/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc @@ -404,6 +404,7 @@ DEFINE DO_KCS = 0 # gAmdStyxTokenSpaceGuid.PcdSata0PortCount|2 gAmdStyxTokenSpaceGuid.PcdSata1PortCount|0 + gAmdStyxTokenSpaceGuid.PcdSataPortMode|0xf
# PCIe Support gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xF0000000 diff --git a/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc b/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc index f6d2d37014dd..298cf3eb1c28 100644 --- a/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc +++ b/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc @@ -406,6 +406,8 @@ DEFINE DO_KCS = 1 # gAmdStyxTokenSpaceGuid.PcdSata0PortCount|2 gAmdStyxTokenSpaceGuid.PcdSata1PortCount|0 + gAmdStyxTokenSpaceGuid.PcdSataPortMode|0xf +
# PCIe Support gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xF0000000 diff --git a/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc b/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc index 9d533149af07..6c284fb3b7db 100644 --- a/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc +++ b/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc @@ -415,7 +415,7 @@ DEFINE DO_KCS = 1 # will crash the firmware. So use the first controller only. # gAmdStyxTokenSpaceGuid.PcdSata0PortCount|8 - gAmdStyxTokenSpaceGuid.PcdSata1PortCount|0 + gAmdStyxTokenSpaceGuid.PcdSataPortMode|0xffff
# PCIe Support gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xF0000000
On Tue, Jun 27, 2017 at 01:21:38PM +0000, Ard Biesheuvel wrote:
The SATA related PCDs consumed by AmdSataInitLib contain a PcdSataPortMode PCD that sets the port mode to all ports. This PCD defaults to zero, while the code in question has no default, i.e., the value 0 is not treated as either 1, 2 or 3, and so the init sequence is not carried out correctly.
Could you slip a "Gen" in there somewhere before pushing? (I know it is in subject line as well.)
While observed SATA link detection issues on CelloBoard appear to be unrelated to this (i.e., this change did not improve the situation), let's set the correct values nonetheless.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org
Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc | 1 + Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc | 2 ++ Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc b/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc index ddb944d0beb4..d10c0901c811 100644 --- a/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc +++ b/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc @@ -404,6 +404,7 @@ DEFINE DO_KCS = 0 # gAmdStyxTokenSpaceGuid.PcdSata0PortCount|2 gAmdStyxTokenSpaceGuid.PcdSata1PortCount|0
- gAmdStyxTokenSpaceGuid.PcdSataPortMode|0xf
# PCIe Support gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xF0000000 diff --git a/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc b/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc index f6d2d37014dd..298cf3eb1c28 100644 --- a/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc +++ b/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc @@ -406,6 +406,8 @@ DEFINE DO_KCS = 1 # gAmdStyxTokenSpaceGuid.PcdSata0PortCount|2 gAmdStyxTokenSpaceGuid.PcdSata1PortCount|0
- gAmdStyxTokenSpaceGuid.PcdSataPortMode|0xf
# PCIe Support gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xF0000000 diff --git a/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc b/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc index 9d533149af07..6c284fb3b7db 100644 --- a/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc +++ b/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc @@ -415,7 +415,7 @@ DEFINE DO_KCS = 1 # will crash the firmware. So use the first controller only. # gAmdStyxTokenSpaceGuid.PcdSata0PortCount|8
- gAmdStyxTokenSpaceGuid.PcdSata1PortCount|0
- gAmdStyxTokenSpaceGuid.PcdSataPortMode|0xffff
# PCIe Support gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xF0000000 -- 2.9.3
Reviewed-by: Leif Lindholm leif.lindholm@linaro.org
On 27 June 2017 at 16:03, Leif Lindholm leif.lindholm@linaro.org wrote:
On Tue, Jun 27, 2017 at 01:21:38PM +0000, Ard Biesheuvel wrote:
The SATA related PCDs consumed by AmdSataInitLib contain a PcdSataPortMode PCD that sets the port mode to all ports. This PCD defaults to zero, while the code in question has no default, i.e., the value 0 is not treated as either 1, 2 or 3, and so the init sequence is not carried out correctly.
Could you slip a "Gen" in there somewhere before pushing? (I know it is in subject line as well.)
Sure.
While observed SATA link detection issues on CelloBoard appear to be unrelated to this (i.e., this change did not improve the situation), let's set the correct values nonetheless.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org
Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc | 1 + Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc | 2 ++ Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc b/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc index ddb944d0beb4..d10c0901c811 100644 --- a/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc +++ b/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc @@ -404,6 +404,7 @@ DEFINE DO_KCS = 0 # gAmdStyxTokenSpaceGuid.PcdSata0PortCount|2 gAmdStyxTokenSpaceGuid.PcdSata1PortCount|0
gAmdStyxTokenSpaceGuid.PcdSataPortMode|0xf
# PCIe Support gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xF0000000
diff --git a/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc b/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc index f6d2d37014dd..298cf3eb1c28 100644 --- a/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc +++ b/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc @@ -406,6 +406,8 @@ DEFINE DO_KCS = 1 # gAmdStyxTokenSpaceGuid.PcdSata0PortCount|2 gAmdStyxTokenSpaceGuid.PcdSata1PortCount|0
gAmdStyxTokenSpaceGuid.PcdSataPortMode|0xf
# PCIe Support gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xF0000000
diff --git a/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc b/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc index 9d533149af07..6c284fb3b7db 100644 --- a/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc +++ b/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc @@ -415,7 +415,7 @@ DEFINE DO_KCS = 1 # will crash the firmware. So use the first controller only. # gAmdStyxTokenSpaceGuid.PcdSata0PortCount|8
- gAmdStyxTokenSpaceGuid.PcdSata1PortCount|0
gAmdStyxTokenSpaceGuid.PcdSataPortMode|0xffff
# PCIe Support gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xF0000000
-- 2.9.3
Reviewed-by: Leif Lindholm leif.lindholm@linaro.org
The logic regarding how the various SMMUs are exposed in the device tree is inverted, in the sense that they are present in the static DTB image, and are removed if no SMMU support is requested.
However, the logic is flawed in the sense that it did not remove SMMUs for hardware that is not there to begin with, i.e., the XGBE network ports on Cello/Softiron 1000 or the second SATA controller on B1 silicon.
So fix that.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org --- Platforms/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/Platforms/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c b/Platforms/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c index 093db6517c1a..0da00655396e 100644 --- a/Platforms/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c +++ b/Platforms/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c @@ -261,11 +261,18 @@ SetSocIdStatus ( if (!PcdGetBool (PcdEnableSmmus)) { DisableSmmu (Fdt, "iommu-map", "/smb/smmu@e0a00000", "/smb/pcie@f0000000"); DisableSmmu (Fdt, "iommus", "/smb/smmu@e0200000", "/smb/sata@e0300000"); + } + + if (!PcdGetBool (PcdEnableSmmus) || !IsRevB1 || FixedPcdGet8 (PcdSata1PortCount) == 0) { DisableSmmu (Fdt, "iommus", "/smb/smmu@e0c00000", "/smb/sata@e0d00000"); + } + #if DO_XGBE + if (!PcdGetBool (PcdEnableSmmus)) +#endif + { DisableSmmu (Fdt, "iommus", "/smb/smmu@e0600000", "/smb/xgmac@e0700000"); DisableSmmu (Fdt, "iommus", "/smb/smmu@e0800000", "/smb/xgmac@e0900000"); -#endif } }
On Tue, Jun 27, 2017 at 01:21:39PM +0000, Ard Biesheuvel wrote:
The logic regarding how the various SMMUs are exposed in the device tree is inverted, in the sense that they are present in the static DTB image, and are removed if no SMMU support is requested.
However, the logic is flawed in the sense that it did not remove SMMUs for hardware that is not there to begin with, i.e., the XGBE network ports on Cello/Softiron 1000 or the second SATA controller on B1 silicon.
So fix that.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org
Platforms/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/Platforms/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c b/Platforms/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c index 093db6517c1a..0da00655396e 100644 --- a/Platforms/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c +++ b/Platforms/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c @@ -261,11 +261,18 @@ SetSocIdStatus ( if (!PcdGetBool (PcdEnableSmmus)) { DisableSmmu (Fdt, "iommu-map", "/smb/smmu@e0a00000", "/smb/pcie@f0000000"); DisableSmmu (Fdt, "iommus", "/smb/smmu@e0200000", "/smb/sata@e0300000");
- }
- if (!PcdGetBool (PcdEnableSmmus) || !IsRevB1 || FixedPcdGet8 (PcdSata1PortCount) == 0) { DisableSmmu (Fdt, "iommus", "/smb/smmu@e0c00000", "/smb/sata@e0d00000");
- }
#if DO_XGBE
- if (!PcdGetBool (PcdEnableSmmus))
+#endif
- { DisableSmmu (Fdt, "iommus", "/smb/smmu@e0600000", "/smb/xgmac@e0700000"); DisableSmmu (Fdt, "iommus", "/smb/smmu@e0800000", "/smb/xgmac@e0900000");
-#endif }
That's a little bit filthy. Could you do
#if !DO_XBGE
Around the whole new if-statement instead?
/ Leif
} -- 2.9.3
On 27 June 2017 at 16:08, Leif Lindholm leif.lindholm@linaro.org wrote:
On Tue, Jun 27, 2017 at 01:21:39PM +0000, Ard Biesheuvel wrote:
The logic regarding how the various SMMUs are exposed in the device tree is inverted, in the sense that they are present in the static DTB image, and are removed if no SMMU support is requested.
However, the logic is flawed in the sense that it did not remove SMMUs for hardware that is not there to begin with, i.e., the XGBE network ports on Cello/Softiron 1000 or the second SATA controller on B1 silicon.
So fix that.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org
Platforms/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/Platforms/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c b/Platforms/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c index 093db6517c1a..0da00655396e 100644 --- a/Platforms/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c +++ b/Platforms/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c @@ -261,11 +261,18 @@ SetSocIdStatus ( if (!PcdGetBool (PcdEnableSmmus)) { DisableSmmu (Fdt, "iommu-map", "/smb/smmu@e0a00000", "/smb/pcie@f0000000"); DisableSmmu (Fdt, "iommus", "/smb/smmu@e0200000", "/smb/sata@e0300000");
- }
- if (!PcdGetBool (PcdEnableSmmus) || !IsRevB1 || FixedPcdGet8 (PcdSata1PortCount) == 0) { DisableSmmu (Fdt, "iommus", "/smb/smmu@e0c00000", "/smb/sata@e0d00000");
- }
#if DO_XGBE
- if (!PcdGetBool (PcdEnableSmmus))
+#endif
- { DisableSmmu (Fdt, "iommus", "/smb/smmu@e0600000", "/smb/xgmac@e0700000"); DisableSmmu (Fdt, "iommus", "/smb/smmu@e0800000", "/smb/xgmac@e0900000");
-#endif }
That's a little bit filthy. Could you do
#if !DO_XBGE
Around the whole new if-statement instead?
Not really. What I actually need is
if (!PcdGetBool (PcdEnableSmmus) || !DO_XGBE)
which is not equivalent. However, this breaks due to the fact the DO_XGBE is not defined to 0 but simply not defined at all.
On 27 June 2017 at 16:11, Ard Biesheuvel ard.biesheuvel@linaro.org wrote:
On 27 June 2017 at 16:08, Leif Lindholm leif.lindholm@linaro.org wrote:
On Tue, Jun 27, 2017 at 01:21:39PM +0000, Ard Biesheuvel wrote:
The logic regarding how the various SMMUs are exposed in the device tree is inverted, in the sense that they are present in the static DTB image, and are removed if no SMMU support is requested.
However, the logic is flawed in the sense that it did not remove SMMUs for hardware that is not there to begin with, i.e., the XGBE network ports on Cello/Softiron 1000 or the second SATA controller on B1 silicon.
So fix that.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org
Platforms/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/Platforms/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c b/Platforms/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c index 093db6517c1a..0da00655396e 100644 --- a/Platforms/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c +++ b/Platforms/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c @@ -261,11 +261,18 @@ SetSocIdStatus ( if (!PcdGetBool (PcdEnableSmmus)) { DisableSmmu (Fdt, "iommu-map", "/smb/smmu@e0a00000", "/smb/pcie@f0000000"); DisableSmmu (Fdt, "iommus", "/smb/smmu@e0200000", "/smb/sata@e0300000");
- }
- if (!PcdGetBool (PcdEnableSmmus) || !IsRevB1 || FixedPcdGet8 (PcdSata1PortCount) == 0) { DisableSmmu (Fdt, "iommus", "/smb/smmu@e0c00000", "/smb/sata@e0d00000");
- }
#if DO_XGBE
- if (!PcdGetBool (PcdEnableSmmus))
+#endif
- { DisableSmmu (Fdt, "iommus", "/smb/smmu@e0600000", "/smb/xgmac@e0700000"); DisableSmmu (Fdt, "iommus", "/smb/smmu@e0800000", "/smb/xgmac@e0900000");
-#endif }
That's a little bit filthy. Could you do
#if !DO_XBGE
Around the whole new if-statement instead?
Not really. What I actually need is
if (!PcdGetBool (PcdEnableSmmus) || !DO_XGBE)
which is not equivalent. However, this breaks due to the fact the DO_XGBE is not defined to 0 but simply not defined at all.
How about
#if DO_XGBE DisableXgbeSmmus = !PcdGetBool (PcdEnableSmmus); #else DisableXgbeSmmus = TRUE; #endif
if (DisableXgbeSmmus) { DisableSmmu (Fdt, "iommus", "/smb/smmu@e0600000", "/smb/xgmac@e0700000"); DisableSmmu (Fdt, "iommus", "/smb/smmu@e0800000", "/smb/xgmac@e0900000"); }
?
On Tue, Jun 27, 2017 at 05:00:12PM +0000, Ard Biesheuvel wrote:
On 27 June 2017 at 16:11, Ard Biesheuvel ard.biesheuvel@linaro.org wrote:
On 27 June 2017 at 16:08, Leif Lindholm leif.lindholm@linaro.org wrote:
On Tue, Jun 27, 2017 at 01:21:39PM +0000, Ard Biesheuvel wrote:
The logic regarding how the various SMMUs are exposed in the device tree is inverted, in the sense that they are present in the static DTB image, and are removed if no SMMU support is requested.
However, the logic is flawed in the sense that it did not remove SMMUs for hardware that is not there to begin with, i.e., the XGBE network ports on Cello/Softiron 1000 or the second SATA controller on B1 silicon.
So fix that.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org
Platforms/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/Platforms/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c b/Platforms/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c index 093db6517c1a..0da00655396e 100644 --- a/Platforms/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c +++ b/Platforms/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c @@ -261,11 +261,18 @@ SetSocIdStatus ( if (!PcdGetBool (PcdEnableSmmus)) { DisableSmmu (Fdt, "iommu-map", "/smb/smmu@e0a00000", "/smb/pcie@f0000000"); DisableSmmu (Fdt, "iommus", "/smb/smmu@e0200000", "/smb/sata@e0300000");
- }
- if (!PcdGetBool (PcdEnableSmmus) || !IsRevB1 || FixedPcdGet8 (PcdSata1PortCount) == 0) { DisableSmmu (Fdt, "iommus", "/smb/smmu@e0c00000", "/smb/sata@e0d00000");
- }
#if DO_XGBE
- if (!PcdGetBool (PcdEnableSmmus))
+#endif
- { DisableSmmu (Fdt, "iommus", "/smb/smmu@e0600000", "/smb/xgmac@e0700000"); DisableSmmu (Fdt, "iommus", "/smb/smmu@e0800000", "/smb/xgmac@e0900000");
-#endif }
That's a little bit filthy. Could you do
#if !DO_XBGE
Around the whole new if-statement instead?
Not really. What I actually need is
if (!PcdGetBool (PcdEnableSmmus) || !DO_XGBE)
which is not equivalent. However, this breaks due to the fact the DO_XGBE is not defined to 0 but simply not defined at all.
How about
#if DO_XGBE DisableXgbeSmmus = !PcdGetBool (PcdEnableSmmus); #else DisableXgbeSmmus = TRUE; #endif
if (DisableXgbeSmmus) { DisableSmmu (Fdt, "iommus", "/smb/smmu@e0600000", "/smb/xgmac@e0700000"); DisableSmmu (Fdt, "iommus", "/smb/smmu@e0800000", "/smb/xgmac@e0900000"); }
?
That looks optimal. With that: Reviewed-by: Leif Lindholm leif.lindholm@linaro.org
Add support for enabling the SMMU descriptions in the device tree and ACPI IORT, so that the OS can attach to them. Note that these platforms only have 2 usable SMMUs: one for the PCIe root complex, and one for the SATA controller.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org --- Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc | 4 +++- Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc b/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc index d10c0901c811..2eec9131a8a8 100644 --- a/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc +++ b/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc @@ -470,9 +470,11 @@ DEFINE DO_KCS = 0 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64|0x0 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64|0x0
-[PcdsDynamicExHii.common.DEFAULT] +[PcdsDynamicHii] gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|5
+ gAmdStyxTokenSpaceGuid.PcdEnableSmmus|L"StyxEnableSmmus"|gAmdStyxVariableGuid|0x0|FALSE + ################################################################################ # # Components Section - list of all EDK II Modules needed by this Platform diff --git a/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc b/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc index 298cf3eb1c28..57d1425b2c8f 100644 --- a/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc +++ b/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc @@ -472,9 +472,11 @@ DEFINE DO_KCS = 1 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64|0x0 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64|0x0
-[PcdsDynamicExHii.common.DEFAULT] +[PcdsDynamicHii] gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|5
+ gAmdStyxTokenSpaceGuid.PcdEnableSmmus|L"StyxEnableSmmus"|gAmdStyxVariableGuid|0x0|FALSE + ################################################################################ # # Components Section - list of all EDK II Modules needed by this Platform
On Tue, Jun 27, 2017 at 01:21:40PM +0000, Ard Biesheuvel wrote:
Add support for enabling the SMMU descriptions in the device tree and ACPI IORT, so that the OS can attach to them. Note that these platforms only have 2 usable SMMUs: one for the PCIe root complex, and one for the SATA controller.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org
With Platform->Platforms in subject: Reviewed-by: Leif Lindholm leif.lindholm@linaro.org
Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc | 4 +++- Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc b/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc index d10c0901c811..2eec9131a8a8 100644 --- a/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc +++ b/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc @@ -470,9 +470,11 @@ DEFINE DO_KCS = 0 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64|0x0 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64|0x0 -[PcdsDynamicExHii.common.DEFAULT] +[PcdsDynamicHii] gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|5
- gAmdStyxTokenSpaceGuid.PcdEnableSmmus|L"StyxEnableSmmus"|gAmdStyxVariableGuid|0x0|FALSE
################################################################################ # # Components Section - list of all EDK II Modules needed by this Platform diff --git a/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc b/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc index 298cf3eb1c28..57d1425b2c8f 100644 --- a/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc +++ b/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc @@ -472,9 +472,11 @@ DEFINE DO_KCS = 1 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64|0x0 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64|0x0 -[PcdsDynamicExHii.common.DEFAULT] +[PcdsDynamicHii] gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|5
- gAmdStyxTokenSpaceGuid.PcdEnableSmmus|L"StyxEnableSmmus"|gAmdStyxVariableGuid|0x0|FALSE
################################################################################ #
# Components Section - list of all EDK II Modules needed by this Platform
2.9.3
Now that we have the ability to switch between ACPI and DT support in the UEFI setup menu, let's add DT support to Cello as well. The change is trivial, and it improves the utility of this board for development.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org --- Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc | 15 ++++++++++++++- Platforms/AMD/Styx/CelloBoard/CelloBoard.fdf | 9 +++++++++ 2 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc b/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc index 2eec9131a8a8..2b041192c887 100644 --- a/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc +++ b/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc @@ -558,6 +558,15 @@ DEFINE DO_KCS = 0 AmdModulePkg/Iscp/IscpDxe.inf
# + # FDT support + # + EmbeddedPkg/Drivers/DtPlatformDxe/DtPlatformDxe.inf { + <LibraryClasses> + FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf + DtPlatformDtbLoaderLib|OpenPlatformPkg/Platforms/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.inf + } + + # # PCI support # AmdModulePkg/Gionb/Gionb.inf @@ -610,7 +619,11 @@ DEFINE DO_KCS = 0 # # ACPI Support # - MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf + MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf { + <LibraryClasses> + NULL|EmbeddedPkg/Library/PlatformHasAcpiLib/PlatformHasAcpiLib.inf + } + OpenPlatformPkg/Platforms/AMD/Styx/AcpiTables/AcpiAml.inf OpenPlatformPkg/Platforms/AMD/Styx/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
diff --git a/Platforms/AMD/Styx/CelloBoard/CelloBoard.fdf b/Platforms/AMD/Styx/CelloBoard/CelloBoard.fdf index 29103531a224..6f7428f0c4ca 100644 --- a/Platforms/AMD/Styx/CelloBoard/CelloBoard.fdf +++ b/Platforms/AMD/Styx/CelloBoard/CelloBoard.fdf @@ -139,6 +139,15 @@ READ_LOCK_STATUS = TRUE INF AmdModulePkg/Iscp/IscpDxe.inf
# + # FDT support + # + INF EmbeddedPkg/Drivers/DtPlatformDxe/DtPlatformDxe.inf + + FILE FREEFORM = 25462CDA-221F-47DF-AC1D-259CFAA4E326 { + SECTION RAW = OpenPlatformPkg/Platforms/AMD/Styx/OverdriveBoard/FdtBlob/styx-overdrive.dtb + } + + # # PCI support # INF AmdModulePkg/Gionb/Gionb.inf
On Tue, Jun 27, 2017 at 01:21:41PM +0000, Ard Biesheuvel wrote:
Now that we have the ability to switch between ACPI and DT support in the UEFI setup menu, let's add DT support to Cello as well. The change is trivial, and it improves the utility of this board for development.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org
Yeah, fair enough. It feels a little weird to include the Overdrive .dtb directly, but there's also a limit to how much re-engineering a limited-run board should be given.
Reviewed-by: Leif Lindholm leif.lindholm@linaro.org
Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc | 15 ++++++++++++++- Platforms/AMD/Styx/CelloBoard/CelloBoard.fdf | 9 +++++++++ 2 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc b/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc index 2eec9131a8a8..2b041192c887 100644 --- a/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc +++ b/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc @@ -558,6 +558,15 @@ DEFINE DO_KCS = 0 AmdModulePkg/Iscp/IscpDxe.inf #
- # FDT support
- #
- EmbeddedPkg/Drivers/DtPlatformDxe/DtPlatformDxe.inf {
<LibraryClasses>
FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
DtPlatformDtbLoaderLib|OpenPlatformPkg/Platforms/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.inf
- }
- # # PCI support # AmdModulePkg/Gionb/Gionb.inf
@@ -610,7 +619,11 @@ DEFINE DO_KCS = 0 # # ACPI Support #
- MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
- MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf {
<LibraryClasses>
NULL|EmbeddedPkg/Library/PlatformHasAcpiLib/PlatformHasAcpiLib.inf
- }
- OpenPlatformPkg/Platforms/AMD/Styx/AcpiTables/AcpiAml.inf OpenPlatformPkg/Platforms/AMD/Styx/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
diff --git a/Platforms/AMD/Styx/CelloBoard/CelloBoard.fdf b/Platforms/AMD/Styx/CelloBoard/CelloBoard.fdf index 29103531a224..6f7428f0c4ca 100644 --- a/Platforms/AMD/Styx/CelloBoard/CelloBoard.fdf +++ b/Platforms/AMD/Styx/CelloBoard/CelloBoard.fdf @@ -139,6 +139,15 @@ READ_LOCK_STATUS = TRUE INF AmdModulePkg/Iscp/IscpDxe.inf #
- # FDT support
- #
- INF EmbeddedPkg/Drivers/DtPlatformDxe/DtPlatformDxe.inf
- FILE FREEFORM = 25462CDA-221F-47DF-AC1D-259CFAA4E326 {
- SECTION RAW = OpenPlatformPkg/Platforms/AMD/Styx/OverdriveBoard/FdtBlob/styx-overdrive.dtb
- }
- # # PCI support # INF AmdModulePkg/Gionb/Gionb.inf
-- 2.9.3
Update the NUM_CORES define to accurately reflect the core count of the SoC part used on the CelloBoard.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org --- Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc b/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc index 2b041192c887..f7d29a49a2dc 100644 --- a/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc +++ b/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc @@ -17,7 +17,7 @@ ################################################################################ [Defines]
-DEFINE NUM_CORES = 8 +DEFINE NUM_CORES = 4 DEFINE DO_KCS = 0
PLATFORM_NAME = Cello
Set the user visible 'firmware vendor' string to 'LeMaker Cello', which is more accurate, and could be helpful when dealing with bug reports, given that it is reported in the Linux kernel log as well.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org --- Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc b/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc index f7d29a49a2dc..091914c047a3 100644 --- a/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc +++ b/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc @@ -357,7 +357,7 @@ DEFINE DO_KCS = 0 gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
- gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVendor|L"AMD Seattle" + gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVendor|L"LeMaker Cello"
# Number of configured cores gArmPlatformTokenSpaceGuid.PcdCoreCount|$(NUM_CORES)
Update binary AmdModulePkg component to new versions built using the GCC5 toolchain profile using GCC 6.2.0.
The following source code changes are incorporated into this build as well
e8d5cf37d2cd AmdModulePkg: bring .DSC up to date with recent EDK2 changes bdfcb308553b AmdModulePkg/Gionb: avoid hang in reconfigure routine
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org --- Platforms/AMD/Styx/Binary/AmdModulePkg/Gionb/Gionb.efi | Bin 43296 -> 36768 bytes Platforms/AMD/Styx/Binary/AmdModulePkg/Gionb/Gionb.inf | 14 ++++++-------- Platforms/AMD/Styx/Binary/AmdModulePkg/Iscp/IscpDxe.efi | Bin 262144 -> 262144 bytes Platforms/AMD/Styx/Binary/AmdModulePkg/Iscp/IscpPei.efi | Bin 10336 -> 6976 bytes Platforms/AMD/Styx/Binary/AmdModulePkg/SnpDxe/SnpDxePort0.efi | Bin 30272 -> 24992 bytes Platforms/AMD/Styx/Binary/AmdModulePkg/SnpDxe/SnpDxePort1.efi | Bin 30272 -> 24992 bytes 6 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/Platforms/AMD/Styx/Binary/AmdModulePkg/Gionb/Gionb.efi b/Platforms/AMD/Styx/Binary/AmdModulePkg/Gionb/Gionb.efi index bbd2e1c2ad9d42a3ce9a4442188807bdceba50b7..4cf762b8ad110ff2e27285ac2773b0e979792480 100644 GIT binary patch literal 36768 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
literal 43296 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 RW1_(6d)~a~z&#(8|8IuDG%NrB
diff --git a/Platforms/AMD/Styx/Binary/AmdModulePkg/Gionb/Gionb.inf b/Platforms/AMD/Styx/Binary/AmdModulePkg/Gionb/Gionb.inf index 9b06cf6393c6..867fd513ff9b 100644 --- a/Platforms/AMD/Styx/Binary/AmdModulePkg/Gionb/Gionb.inf +++ b/Platforms/AMD/Styx/Binary/AmdModulePkg/Gionb/Gionb.inf @@ -41,11 +41,9 @@ ENTRY_POINT = PeiInitGionb AmdModulePkg/AmdModulePkg.dec
[PatchPcd] - gAmdModulePkgTokenSpaceGuid.PcdPcieCoreConfiguration|2|0xa4d9 - gAmdModulePkgTokenSpaceGuid.PcdPciePort0Present|1|0xa4c2 - gAmdModulePkgTokenSpaceGuid.PcdPciePort1Present|1|0xa4ab - gAmdModulePkgTokenSpaceGuid.PcdPciePort2Present|1|0xa4d8 - gAmdModulePkgTokenSpaceGuid.PcdPcieHardcodeEnumeration|TRUE|0xa4ac - gAmdModulePkgTokenSpaceGuid.PcdPcieGenMax|2|0xa4ad - gAmdModulePkgTokenSpaceGuid.PcdPcieGen3|0|0xa4c1 - gAmdModulePkgTokenSpaceGuid.PcdPcieGen2|0|0xa4c0 + gAmdModulePkgTokenSpaceGuid.PcdPcieCoreConfiguration|2|0x8B60 + gAmdModulePkgTokenSpaceGuid.PcdPcieHardcodeEnumeration|TRUE|0x8C7C + gAmdModulePkgTokenSpaceGuid.PcdPcieGenMax|2|0x8ECC + gAmdModulePkgTokenSpaceGuid.PcdPciePort0Present|1|0x8ECD + gAmdModulePkgTokenSpaceGuid.PcdPciePort1Present|1|0x8ECE + gAmdModulePkgTokenSpaceGuid.PcdPciePort2Present|1|0x8ECF diff --git a/Platforms/AMD/Styx/Binary/AmdModulePkg/Iscp/IscpDxe.efi b/Platforms/AMD/Styx/Binary/AmdModulePkg/Iscp/IscpDxe.efi index 3bfc2a8a4cfbc01b59a98d86da33223489ef600b..9d02adc18b52ad5e2b8a9c6187264d223a83854e 100644 GIT binary patch literal 262144 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 z?xxxLKl9cso;`1V^r|oWzh<>ATb6lFmJvVz0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILK;VyAz?6$KRC9bu{HFMtcr3m-eoy@2cs$-2 z-yZLZ_r%|b|2+PFJQ?2?KM?PWt8GQwLfihBJ-9Xm5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** p5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0;7?QF{{gH5{r>;}
literal 262144 zcmeI(4RloHoyYO#&V(eqxQ-@}@UmtCSP`vYMNO(TH;GhqvD$zyt$PkZLW_k~<wa2} z3~E;vY&8_Mbzc~;yN8+Go^2H+*cTIDTD9#tZ7}L~d+G$VRoQI|2xO>|{XO?3nG6YF zv_0FiU(bp6&Yk=6JfHvb{O|MJxm^BPGwA=WJv`_`IS>H^5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R;XZ30yhdn5J~JPmTXz&N9Oz zc9RqQ8B>+B?(f|Do&P!fe?iYNBf?F`SjLX=ec!KbSsgROiI@lbe(`}mowaoS@}=Gx z!g__v-qXg7X*{cG?$WtE`&lHrpNHjbwf}RCX+3N4{6#m;v!CquewqEH-RA%28dDdp zA8Wa9)(=zfL{0keaFf;bH|*1T(sXT06cxuD<7P9_()4GvJrga_K5lm3tf#lMM(4b| zZ`Sv9oRi*vos&9Xk1sLV<a<T2{aUxjbyk?HV-oGoMkiKj-0f|~OuKWKyFDIFv>Wq> zy)`DXa7NV3&O}G0J9UlIbdAJ6Ia5{3>PE**bECzvozIx&+N7f}y4mPVTb5DjMpN^0 z=U6xE9_o(8&oo(ktlfTgQ1*oBdLrC*Mo{jZ6>fG@#Ld<k=fzrMwhqzu{nyo|4wu;a zJnPjb`AzRS)vk%3w|b~4b<L#nZqw4Q>km`b#n#t4-9FrG@UKyl9zUXYeNxW)<ec@( zbJjndvmSb`8evMC^mj|KDK#>)*F1b;MOS6ENOe!Ne?iC89`e^eul2)4wOwsp{^xl* zZr_S0Q#<w)#T+Nm-l%$JrkJcf&PjY{Z)TopuDHXbGLHnyUBPmK<8QyqX?E@%+x0n} zH*=z!bs{=W@u@Iok1?ws-Z{n1&dsrVqPzQ{eJg(Cw*g(Z<ab4}$`5ee8OM3uZ{%Kg z*7nq_w~Jyn9?p=U&gc7ew(%LTuJeLAtIbRvYBt0(8{3WBvNy9Mk}^6^Mr}4TFTQSq zEmK)P7U%c1SfVodG5m4RC$^_b{#$)ug_FAKjiOl6#v&-!vC0%TiH6MAO|>!KZ&w{Q zn5D%hJLaDoI?Ixa9pg;4+Yf2Gjc@JRwGFjv(u?nmBpMuJwi_qWU}F@InQFTnUuvrB zbUtsr+*C&tAMg8drn>Vk(`?V7+_LW6V*h**d!BJ_b!p74t}*83%GjM_rkT>=8zTib z&xn}WYU`7Kt$j`CRc5k@*KPY#{l>~&=lAT?#$HkxtzE*H$L)3Ov28lGQ+7#PMq^%d z)dwfaZvTqf)V^7v-L};DNv1i>DOdkjQLI(_XD;#MdT?GOl~J3`u85|*_8i9YkszkK z{G|+<m3L$(%L1*-!a37aSD47|x!v8fOI|CAwVb}DVfmyji`8EmBFaaNx=y(q?NV8w zx=q`?bsbwPM{iw@PBd7TqpR&U2P7i?aVBn>JB#{yj?D2q*Nhzglss=RX7)Aen-h&G z?Tn6`JX+VkM?P8GXG7o9<oln2?-^>7s`pB{9z4y>Zi|GjBPTD^ab8@NUn@-c!rJ$` zXU9w3>WV6JbLYESS4=A!&CRRrdbwNezT187&gkfLrOIma`r|6E?jWUQ>hopl^E)qb zvu!f4c`_3%OV=t+PaamBlq(O;t4n29)GJ;u1Z{m=>amxKVrp9r_8!pjv!K2A6R+jz zzi&9GzFM_l%i^QO&N_#2h$s#_gE&Nj_H4h8*!CR6Ari#F#xNel&&FX@UL5*s*ESAU z_r#&pi^Hk?#KBd)ymlVMVVvS{Kyi4YCk~~PhYl2n3y&ubW$9T#97ZV)qk=eW>WRZB zFAmopB@RoUFN*DxukFV+7Pqtw+;?h<&285zf7Hlv`GQnWJZfZF6IVa+?iEgR%|v~k zq&BY@c-w;hl?Y;Fm$t9ye$n8q2Ytm`*SS~gIB#9&wYjZP{ltE@eZuCNFwYFsFTSaq z(k7Sue$m?6Hy$m+di#YvzwJ~1qT^O;J)Yk$+?;q!9jITFq<>#{?0)gidjt22ec$Wt z7b71ZxL?>f*nW{4htNOQyis+@?HA)^Znx$4i#x;q5}50ApMJ4j_41B8O1{tU7d8%a z`iVngYu`9rtvKZOi+UY5x4$@Cd^~X|OMf+p!_oT1`lH0*vH$3eL&uhZ<8W*7+J-L0 zVOzSlKMWLyvLMgc{4_rF&d*N;L3|X4NP&NUv3cn;gYX}%<GXcSem_X4KDl}6fW|ZV z{=0NsuYXzZ{b6E`e`271P@ewiarl4iX#S7n`2XXF?_c*m{j)>ffBU!o8~gKDeRBOD z?8pDEf&3>Opa0KPUVDE&TKjK*cc47flA7bXH{1Kc{`&*_nqVxoLSw1?dBD729QBC5 z4D-Mzb^XkSqS!>`@CTI(N**YRooAAJ52n^ML^b|<<%RU(CiMxsKDWSZ@6=q(x<rc2 z_D`$+Hs5&TEajZA@7VjsrXY59e3m=Ls$E|cv&U4Z@7Sg0j#=kblNxAz`sSf-Z+v>5 zu601;rk*jB#`2B#1u>eSF_h~2Q5z%81xMxFyT^oO)V-p{lr5aw)jiwM7^-HPx!JMn zx>vOw>^|3M{FKnLPdsXR=aqI2TC4HWm%@0gsMA>K`JS=Ttaa)OGO+PjcK5)2;o2?1 zSZQe58=rc4C@(gd;9hKf!ux_}8r&E1O`RYgIl+A)qkFLzmjTB7VeI`es>Vj@1HV>V z%+EoMsz+`g=+HPQKL<Un<9c&Y&KPy}@$`YR^oZl=11E*%M~qQ>`#{I?57r0Vm3|+v zeR1C%ejnJj#qR@Umkrzp?pOIeYqfV9|J**%GoQ%o19NX5Tpw7bYvuO=_tw6BV3Cbc zULW{OSjPN5&@{L{@a;baIVrCXoU^3&esI;If&0L%={4T{_@Q*VXMB1*_v5;7UXXu3 z4!7I;aWLOAx*snq7{vWR$B&g)eqS)EPi|j0xu3q!t?Tvng`E5Gf}FlE;C!t-eW{M` zlYcZ{+oT-e&)59?^Qq9jpT2O;=Zj*G$in8Js~U@92X!Af_`=$TYu0XAd>}e9oz%H9 z!9C(w_XpdiZCkd_9<JBAtDJ6^^|G(my~119Jiz<Ty6fIykFn1k%8t|hD$UR0-aNT< z@(*=PZf;Mg{GPXRyZ8J-x!;y~tHzxB)xOWo$?=<l>*=|qm*ed`*~{@ueRpp@68FbJ zHqYC6vUMJ*zCO~<$CT&WRCeEaq?hO4In;j}-*A=YV%HVLo{@7x$7F)}ur;^yc>5gV zu%4ORGI>qIgKuwHY{&n{%JHKH>HLGJ-@c>DI}zo2M{}<^#@t*NyK9W<GQ7t4&m*k! z1l4!GoXQoa(78*`Br<Z1t4_IX`#Ni^Iq>6wv6ETdK10X$w(U_1=Z4QBmMe$YbzQ$g z#+!m?5sluni1Ku$DPL!wHLO=z`<Sb3ug)`nC^T2wKCEZJz0V?AQnRisitP&8_OeU; zwtcINANoT2&)T*d19O|}2O6{3`)h97F3M}$NtM69w*8*QD*0{u?cjPxwCy_v-?l#y zI_Kx_=|!=q#u8rsxM<+~eT~L2c0P4$@$u#F!Q_y_<8<!xj7M$z-*sGm?vAT2x$XNA zZ!FpO8PEMXuD5;X<nBaH?hbNDpJ#1mwAy!h`j?So=kC|C1CQl*e9Rvcg!$RaC(3vB zcbEOL)>xu_l>WS2qCC@YPEn3uq<Yvff*U?-d?o751wN-bzoWdlRnKkh7(SzYXK7#C zCrgzFOM^UU4g5S<>gB;lgEITSrG(?%CsM0|xyPuF2G63d2<9I4Ij+XD*@e;6Vdd`r z?(3Ne5wHBVpV()mSE~#!O)ZLLqmlG@-CMe%(a8@fmXB$h&9UceK5|I&kzZ;q5>c+) zsqgJ}$D5Cg)-zh&ccz-=Xlq5wa>c=Z?o`e>UG;0U`vqgOF*?@!tb3V#e&wy_jm>IR zAG^KJ{Nz{u{G`9<y~W=AWaQ+((zOoS-vUB+<<`c@LAyIgc~&Mv6oZ5Mz2*F9?=#-L zDz8@#@7^_L;p&6Iy-UxpD($-RYUcreev;HO5!BUbozv2-V{H!I87-fjvCn;FP!+Vp zo@c&S<lfu-XTG1vZHEi%6(^f(Ukv6ly|F#-ln*Di?^GTc+a20w>+*hL>*U1t(a^1* z*v=gwwsTdV!Nm3<T`NDfiLrfS`!$Uj^JBXrEMtCb&pdW)*XY>%*tR)-e?3}kf7F$e zV~!Hrt55uJV!NTVZ)|PZ_MO}t+b1=L8l(Bsfc@50zfDxMtX17?d$9fXg3zs>*me#u z2X0e+1{2$OKe0`Y=o{Ozeqvh?mN7rJe|wbJs;*9APRmL8vDNm=jw7~L9A|8AF&|EB zw+=Znwj~AcKei<~v3*wSHctKJ<bmePovP1ZVw=*n^80P;dxid3Ajru{jm`4=?N`Gx z=Et`2*s*<B$M)&BitP@)k6`b!N9(t*9z0sV-IkiwRT#5lf(P~#`oB8|^N!r#P3>I6 zsY|rqcG;SSaxKF#!uA`2aoQunxM5eYRA1A(7=7X~I_Dl)J3wE{jYaMlxGZB*xxX!k z&zUM!cl$f>bY08NIePAqcATR6<c`fQR6Gu7?r}@b{O<Iyj9xrOdvgzOemBFPd)P9x zX};k-!_%@;<1stuIA6zE_oF>uy*<}G=l9RV?+RlP`<&A;k2}U>TmPppHh!v}SDvYD z!Dnx~_pZ$MQZKz;sNd*J+M9Fhw^ti0J8ny;t=l=4(KyHc#^0@Rf|+T5`(NKsS=#&C z{~xv8zJsIRx6(`AE{tXL`?+<F>bUVc3uDe#OswErZnpK!!dOD@$RrE9w%PAr{%xV= zMWfRC&8WRiW2Xo7dFyWqV+Exe6X~<v*Y3AV=MDEc^1D(y?(&Y${VuLLwdvS5>Ye7h z6DDTMQup>@y*DHeeYZ*9J$3IXUG}rPt1z}&pY6JSGxVMX6t<`gZla+zD8n03r}^1c z{&_a<*Lk#G?mjye_fDO|jz4SlthFSJjW<tu&KsX-e!Hh2R(r_R*imut-rtEDC*4%+ zuHUHd+~P|Py;W#tR~TpaX1&``A2+`!P`T&*;mhmi#ZB|63!1uyEST7Jx7IhB=<d~e zXQ0wV*VXBGyWd8=NAMMWPU`$0S<qB<x85-*TySdDq3-T7``*qCC+M8T?%pAK&QYnq z-$aL`Uss%sV`je|jp{w8=ue7Ot~xDuMWa9YSDkC3{yH_by~{+r?{v;zY%DO}%^dEY z{dd~$O<m{t;2INE-Zs^Jwf3E_vOc$<va2&%kPfduufScu%ByF6-+IP^dcL!A{XD%R zp?bEco-KE4y-z)L{PEQDbQ#tc{0Zx+^5)dDMfGgSt*4EjZExy-vsWo5HXaif%&RI` zFrjLmV)Dlz9&c%Tojm8rGokef3$CwE*M`Ge&1bhe$ic|@pqBVR!ddeQvgKoV#M| zOLn<$)(=ukbbN_9XKkr**4ci0K(X4dSlYSQsz~YX%{s5`n@b`i*R@7!Ubg4%eZTCP zEejpJqow!ka^E5ARPM3wkL*%Tu*cR7F|jw)r;mKkuJ3U>@{W5tVq&ix$8pc)A7@PL zg?^5U-%{LR>m9#+xW8NxESCk#mHyHV_H$SI`@6UM%Zg>i9UE(+9k1!no~O31szdJ; z>=~gr*%+zcK5o?hO{}UzZ**#TVTbLfCU#MW^8BOW{y)|Jw$Ft7SKOoXp6{R6#L7E{ z>6nUpM&xW8*P-|NwC%5Qww*G#a&)a)AC_aL%Fx=U+~pm%EQMZ~$7y{;hrNfG*eP1q zwFg=EP3F$^dZ%-3c-<qt$^)-)f!8U6zLuQVzyH{*?1{~vv}|2p?y>)qUdJr`Gu3Cw z2d|IXUw+^5`^<&vGpl;*am0S*L0cI&__orua?s_sZOs1JcUe1?=RRVpJDw?CuzudV z*X)QEn61N<zw3rvw(h4BpMLn>p}Id0HG6jJo;=Kq@%rru?SH4X*XbTrkVv%K`{Lar zX0H88to5@+=Kl8I>ho`>&0PDI?tf=gKKHQe3{UTlKmD*V!_#q7^YZCK%%011|JHtc z-qyYJvY~o6%naMTNY9|dern&PwPk!N$X9l|{ruXo@>grnA6tX|*m@kfrnSmDw`sjF zSYG5UJENy)e5Ln#?Kok?P2Rh=bLHSFN1B2~kGjftj_O~hTslX&^i1WXgkoJ6<WgH+ z_axgED%ZLvjq}dwo@Dc>{d|h|c~#u6SJL=paDRS*zu(Wtdds+CVb5a<{O{wz(gf!- zI=^=vmBB8@*Im%@+7*62j_aPV@q%bay}nze^4)9S>sA@-gYp%t9z(OM)(=%ZtgE9j zp!K%*8ZWPFy*T(zzh{>g>z?56KdztsmGiy*{qOW|0kr=`!Tx>>`kvp<$;Hag_S)m? z{Q4@V8`~~Vmb)|a${h)fg>73f@wPGM4)^P}jv9Z(>^}C{dZMd4_Sbp`Ph;lxu+8Wc z`Y-S@zGqx66=w9}OxeaU_8k7_F+HDcEbaE5JfGKR<H7gwm><W1_Y1Bot3KzGds62N z@0%tbw9|OdPUHQw)4Vd6c$J?w;um%}CzxyPeaYG#?K-ZGvG;RV$JpHD#xL@`kA93_ zHa94n+h5u8>$BOvj@j&A$80|Kb<F0#U~^!wx!1sJyQ-V3wyWQ#dd4Yk(01qQUT^DF zsr$UGS7qKkexT!QySB&K@qs-qe{2x;OQZf7+8X5$>oq6ns~dx**<0;xH+x6-$>X;5 zb$kCAbLVY^F_k&ns-<oJu9lUWkJ@$HX6<?7cAMs>x!c0;?7!zI(SG)M!9nHf#I64G z1p8a%0p+D~{kAYt^W7SqFL|D;aj)4OQI6X5aW}hkW%)nY`E;czU8nii20a^JoUv_6 z-<4`xVwmQo5x*REjJBlEH2>a?&+TuG`duM>zu5mx&;R!r&Qi^BPc*S#YQM}9m0SH& z<*v5%$Sl@edc{+zbF`eU@4hv{pEIhTW{o~;yzdzdG|xQMJHBm8(=h+I$a~!}JI}QH z`}5I?m%a1fSm-@ha;kLRoBZbxapTXI_pNB#Vz;+yANzbFZYo|L|0P{p>veHA>*}-3 z9jmp?8fP`uPJXd)YFLjjhdBB^S!7~K)l=u$ZtJIdZqG!W$zEM`j>2*Ese;nFRAfYL z$`rUMjW=I<OSx+N2~H|LME|xUIy7zfwb#?{j_oquP+`m-n}fpZC@wwoVsE?}v<W*m zifEo{-;cNB?E=$UJwbn(6E0k>7#hu`D)rapm#?}~|2{|g;3xKaw*7_wUG;~5JFVrr zADNk$vGl(4pWOV~H*Pspa`y8-zVx2A@2h|J=}$lS{DvP7`TZBJytsM!i#N?$_Jigp zr+s@!<i^sv2hO@YS^c#$wm){?n|HkOH@AKAo-JEm{q-9soH286^{uab{iTy0{<yjS zw3@cdH=RB9y6YckKj~{VCi%h*i!TVT%Mt+u5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0;rFH4|%m|xy&M>yWftHb=|ngV}WRp>8Ui~Qx4L;dCKG5&Ju zIDh%-3I1}#DgN@!3V->ln7?c~(O*7W87v)td11s~E;!j=zFFcgXO8rj&yMn!lgj<& zw?_NRt-*2s7qufQ)b09faw6W}r|Qn0np@5(3vT@4{3&x6H%+;I*$s=Drp#|z_^~N< z-fHa^n=ZexY1yLrS1$bgl!oaur`OJ!KIfA9`f1fuYHJ(nXPh@}N}pXWT{7>cDfWLC zFP}f<;^}o)T@rpet7*}q+>5e~00IagfB*srAb<b@2q1s}0tg_000IagfB*srAb<b@ z2q1s}0tg_000IagfB*srAb<b@2q1s}0tg_000IagfB*srAb<b@2q1s}0tg_000Iag zfB*srAb<b@2q1s}0tg_000IagfB*srAb<b@2q1s}0tg_000IagfB*srAb<b@2q1s} z0tg_000IagfB*srAb<b@2q1s}0tg_000IagfB*srAb<b@2q1s}0tg_000IagfB*sr zAb<b@2q1s}0tg_000IagfB*srAb<b@2q1s}0tg_000IagfB*srAb<b@2q1s}0tg_0 z00IagfB*srAb<b@2q1s}0tg_000IagfB*srAb<b@2q1s}0tg_000IagfB*srAb<b@ z2q1s}0tg_000IagfB*srAb<b@2pm%&qCFf_oQx&Qlkw!F<kVzU(oN1tUYWc$*_d3A zyeYXnnMkfl-k<zNGMU_x{7$kZdCZft0|E#jfB*srAb<b@2q1s}0tg_000IagfB*sr zAb<b@2q1s}0tg_000IagfB*srAb<b@2q1s}0tg_000IagfB*srAb<b@2q1s}0tg_0 z00IagfB*srAb<b@2q1s}0tg_000IagfB*srAb<b@2q1s}0tg_000IagfB*srAb<b@ z2q1s}0tg_000IagfB*srAb<b@2q1s}0tg_000IagfB*srAb<b@2q1s}0tg_000Iag zfB*srAb<b@2q1s}0tg_000IagfB*srAb<b@2q1s}0tg_000IagfB*srAb<b@2q1s} z0tg_000IagfB*srAb<b@2q1s}0tg_000IagfB*srAb<b@2q1s}0tg_000IagfB*sr kAb<b@2q1s}0tg_000IagfB*srAb<b@2q1vKUzouE0_6lFrT_o{
diff --git a/Platforms/AMD/Styx/Binary/AmdModulePkg/Iscp/IscpPei.efi b/Platforms/AMD/Styx/Binary/AmdModulePkg/Iscp/IscpPei.efi index 7e917fd75ee3b892ec17ce4fc9a5084035af37e7..262a3c05a1d6b4f7e0c77659efc2d28d543128ce 100644 GIT binary patch literal 6976 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
literal 10336 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 WwdS|Vt;<_iwwAS4wT5;Y%KsN*r2R|)
diff --git a/Platforms/AMD/Styx/Binary/AmdModulePkg/SnpDxe/SnpDxePort0.efi b/Platforms/AMD/Styx/Binary/AmdModulePkg/SnpDxe/SnpDxePort0.efi index 7575200e06b8956ebb60eec0c636b207e9796179..2233bb0b1483d90d42dbd0412d4ba8d8159785b4 100644 GIT binary patch literal 24992 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
literal 30272 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 Llb$Ef28H+^U%&<T
diff --git a/Platforms/AMD/Styx/Binary/AmdModulePkg/SnpDxe/SnpDxePort1.efi b/Platforms/AMD/Styx/Binary/AmdModulePkg/SnpDxe/SnpDxePort1.efi index bf2c84d85e491f31d3dc9bddb6692d17724fbdea..36bd44e9e4596e7a40e07f8428dbd5ab7cf2a4a2 100644 GIT binary patch literal 24992 zcmcJ13wTu3wf{b6h7cgikhcNJOh^$Z1;h|YOU=n7_^609Nwu}TWhMcOU{PKg8zm=^ zQfpf4P?a|NNrIwIe6%7c<BKHHYOU8>CyKqcS0^EATdXw`kPKMn{(fi9o*Yhw|JSeI z|K|Hn&faVN*4k^Y{WyECea>8dwfMLH^nY7&L~!{MAy#%eMhHlKD&~j@su1n}flEoS zUcW>L4K(@ZMuM09uiZa_n_y?2A@4c^Jr!Apem58geM0O^1^72<b2hDN*aTVDne~)+ zt2(z3zBw!Xn_z<Bm&l5dyA`Ji(KTnos_U+=PuMDL=H2=SoY$KFchW;OdxOWmtptzP ztHIb>NAToEXYkY)Ma;KZ*_)+_LHA~*_U5SSI_eOeZig0AGPIab^srl$ABt20w_OXh z3sF+&6zkopsQqkW#UAvA>>E`*oGU(!8Zs^|7OB)?hKwV(^VAo$*s*U{piD2ytVEer z!J(ShAMJ9iIHd1V1B#}Ho1PS*6CbPdnw}A%{U58Y9KAVwRhGE>p5hmx&ATQ9^j+fv zs#6bVi{|j%pj`}J$A{`X{qL$Pa<PaN39SsxP^NyUy1Ynxn0JV>3S7#qdUaou2u1#? zE{|L$V!7bGpC;CO)+x2|jUqHn=;40Uu@85>_=WKKXN$X0zrje}&I0lxYeh)tr(vQq zB*u~5DdoE->EV-*@ql+6{);$rPUB4mJ)R~8iSGkWmQiQ;SB$58<R;h&oi2+G(kVmS zcvFW}-YvxVNF(IdYN0|gc})cE68X`xnT0}Gqa*EmvLbd1{1v$jZHc<G?fh<~cGI4U zm`CW<cb}~VSmsBWz~KHD+}&=a)M(3FAaiS?{bTWX-jzR5O4{KgC+u;+9u@ayTqn<h z>_#o5w<-$;;y(&I&>zV2pv~yhA@J$L6ujuiltsA%@t-B-x*dA>L(uIs`ZNMM%coDg zECY71jCaj4Qt+a^;1N$=zr)cfW&YEo(>Bt{H+j+Df>(?@>v7oO?5r@$=`!h*A)S1a z7Y%`T<!hpZzNrG8I-5<oJ>Zc>9%U`O=wskjf=55}L8ch#9$dSV^qkY^J3%Lgc*6$h ztU&&kNqWv{^q+(Nj3P>icLGOW^q4X~0gryQ)3+IPv<tAe;c5XM{UxlMcsu<EpqFNe zl44-kF0`wgc(lz%@E%G74SAJ%&_783KIkmB9@j2hlKwr=sYd~hdirq@?+4x9FIgAr zpg)Nx?y3|x>SJ3`pTu3B0!LlcNvy<Grod63-R?5rNVnU4K??a)cF#<KOJ#Rq3S26? zb5h`_&)z;0fO`n-au_^o`-}mddhPX$XC&&`PZ{{rWBNS?y0n8lNgp!tc0GSTgPxDh zpr;S?t)@LixOd=Ud;bY^q3hukyy#otJ@cd}A-@>&(KOh#3vwJUkd3|$ekIc6bL=^h z?g56p-+<>FGfF0Wz?31DGA2G80-btDpN6Xrmz+=bfLCnN44);+2tUp;K)(%_mp;Rt zb$ZyM%f^fD1n*wd=|Nyu;$q*Ia=!qNH1dRg8ZR0EZvbUbpNh+mi)FQ%Wu@Rnw}R(1 zW$1I$Z{aPbObTA~Ch)3&rC(Ur4zrx~CY^SXPQJ;Du3<UARpM$Hp@&z>az^u_|6!3S zf=o9stj|?884EAE9K2_Ci;|V5zJA;l^Eq`Xc%;)l+F{{Ez2Hgz81|t&mbKVIS82CN zF9n@`rVQIh(&t(6;7j@}3!VDAO+CdHI`vEXRGWTD&$r^CU(z#e_-0do2I!>^B<5|} z%d#s>e~bZ-z9<IW#*3bs0AB%1I_;7&!=O_p1ur@X-d5m=W&6u{{fJ4YoTQujq66R^ zl;xPR^!s}zoic_EBfRK4;0+*OkIRco&f{-_PJ9Yp^fimjF3R9yIR|Yr7GCs4@QQ(} z!$rIMux_EuvnHKs(rE*EPl3*LQahf-lp{^nm)M{wr`q&A2s-<btY?SWJ_~{S9M^po zKHE?7?=kh!4=uPn;IW*aS?K*1`j0`k`o|&@ZDAR}lFxRdPE%jBk#Y{Lj5N-NbttEB zhFEW`>oV_e+X%jvlAqH#0RCE2ekJ4!Mc!JU5VeKrV*LQt$<$E^dJlB^arc?J3@p~N zr(<(Y!%F|uSnQ*1oF}aIU1qWGbbi9V%74MWB2(|8f5AS9{SvUnutl!pdXVnGbzYL5 zSjS1a2lQvQ;aLV>eh1|p$8{U)BBrdBzGiz;N3LlHdGs;Yc*IKnRY<e%WB^Bf(~$0g zz7DL@lD^5?+2%C$jON2P;D0`TM7}?T{88}P_LM)JpOF99l&5W8yFBb3Fy%+{6K(Tn z@T(vzeOQOI2iKt_J>f%1{{!g6ZUv?u*DjRl&(y=O8T6b{^n;+6IudK=Dqvrx46bHe zFPbuT`m>-@Kg;RESa}fXI><hiq;ow#LVpZ&Yd@g=3S7IB^h6ybeWyw1+);WWVVf6t zw)-z^GLpU>^d9gNHmS+={!c)6f}Y^fF4fq#ZUddz0r2Q26<0Sd-JrwwHu?`FKE5-# zkLz>k;Y|{6qpt(~%Jrh85_(t;pOGt(Za!NNe-Av;nJ1lnmvleq#U`G0?}1PIkpFg) zZjKj|{teK%@3G3T9VoNRCL`&WB<Ul2E8@LLdZG-~)U((ugLQBMC)>IL`~~32y_J<d z*PxH!>08f4J$w~pzJs;&c{Vx8_key{T_D#7zf4ZjNBTPHIZ1k=E_J|jd{0c$NARSN z1D$ihVc?2jO9garJ~sLR#-ai~$MR@?Vl2kSjr18=U;hL>JY>)lea1@vyA9uia*6-Q zhL`j{8@|ZI|H+1z^tWwzwsAA`|CbFf>A$n#SuXJ}+whY9q7Bb-iGS9Hm-MG>c$V7% z{9`t}r0=%jSuXKAZFoulr47$=iT}9`FX=x8UC#Yp+K#@LZ11r<+kObXoV!owqb<R| z6@2#<h{0VUVv%L)yhx3R-FQfpOoJ{tra30qw{F6HF|HdRli=qVV_x#tn6^{`(*wVF zFn1)ML+E>T;CEf7&a?83c$TrwNc6ws6ZPtE0;hjXMVJ_|F1ZHD+EE~5Qr)QIfWtX! z8F1RA>O3obL<agGLtGVb)-k7=^|>%fH|GPBz6f+<yr2#bg2uM=jMKyO4LbDN=(BD3 z9>@?s-G-NRw+&xp;tOneNzb<7X-@_8pKZfSdb$nIa*0=McuD^}{q*{>T;e}7=p*%& z^iOSgmg@)pZ#KN757_W5m-zQ=cuD`G4bO6k58LpP{<;m%a{GY)tqm{fT{b++CH^@Z zUefp4@GO`3CvA91f7FI&xypE~Ic#`Izu$&uxy0XV!%O;IHayEE{tg>n(zn|1EY}14 z78_pD8*F%%OZ)~KUed3#;aM*6*Vyoq?gL%MG7kbP$FCpr#kWiuJH5s%V<qsMKl)h) zuFFA}W1H)-deDkczl%*hc6>z=pIE<1{8vCPot;>RZG{ewd)lkuDgn<*<9dMfh3BcR z&mDQ4v%z;FKMhwu+ZuQ7(WZkQQE>)iiNP0}JY&yjVy6&?J*8U}B~p(HT!)FxK7$@& zs7K<)11I#6*p)>`)NuwK#8U_CjY|CR*n~apSToaJ_6uSZbI<xI_|i`DB>iuo6W?RQ z4^W@Y4^p03DgUl1FHD;(yl8I<9mJ*36MYrfQfF#kcBjx&44dt~eAcwZUYDm*$fvL& z{0MMA%+RZKoWXtYD-p8x0ohObP%it)4}mq#l5qY5TdE~rxV9D$!}BZR1|Ack9}p{W zwgs%j5hGmKXPf6-Y|9%=odb_)#@Uw@OMYY4)&lCg#-gt=YbR*H3#>+`h#KEHV!;Q$ z(n7njNAHfsYguNaLsSbPswa!dvl<IU&GY#fGfi5E=ZFHh2+rxci{iDP49D|$PI3^o zas4l2ReqF5+OJ~qyi{@7Z-FoL)N$Tw@G2qe#AS`yE;Z?tv&VmzfL9EB9WM4^89ymE z%b_m%hI|<dSp=S>?_&Q1kN%%;>S8(6W#L7ePQ>#b1a2kPCakZ=l=%W=Nc$=H)JgmM zamhY^u36Sw;8%fu8?F|VSz(T~9Pn9Q3SRVV@E!t|GO9%;-IPheiz?s|PkppgmUA*K zL1$T{lW+2(N5M<#8li_jG3l<8@jSVAqHfl&1J{S(J8=(#PkqGDZ;U-PV_)(f_@qnP zO`j+9tOTtRR}n7y{w?6@aks8VNq+-$&c$~8t4aLG`jq${1D~D5*O_hmf=PD*!*XQ1 zK4a4_@xKP$ioNAjJntmdnFAPq3vtG3->-V1(~q)tL9Q5S+RQpj`u$1zh=2U>&wZFb z?x78~xpSJKBeCD69mKY#z*)<p&xvbJflKHc@fC450mr$^n72-t?+>8;i0wyRc&2?7 zFas&h$p;pS*mCj~YO$R-hZpG;C)yDYY#fVo>wjV%xk(H8-iw#m{Y1ahPv3;B)pkj* zPSO*8GW-Wy?}eW(1JCX!*(YhU#8#xhS<8~Rg(+|{4q(;yCE(8FC-xWm=`3JQTKpvG zV?l2kJK~>1c&DL*{%M4N-j0_TYXX7$73R4=_Cn2*M6D<siGQo88~b)U=JfH<$GVWu z{#9q;Ilv>`30ftt77Oq5F{jJ*TX@I7lXAC#uA)w|yidRz0F8X|XhVz1{|LND&4}H8 zm#EdxVE3QR^2xW`{Wf@{r?UGEo1E3|S1fXNySu=n-PB8-w3+s^FYO24=sViT+O!*S z{yhdA=j=B6;}Q>D(@cF8xIYYfG468SV>zU^OFc+i@oh<bVt$bLyFsr6R)u^YE<TGI zKr74;gW7obRgP2hJrDMy=2P+70?bPSb)*gTl*c98t_kww(XX_j&cdT^@>YVza$79C z_25w-`Nq6$;jOXgybW~PE6b|~uL`uym>=~s*mN~8<fXEy#^j~4X(@QLiL!Q^mRNM! zZMqOV+O!2WS?3Dc-3>bX!UACI^9sw7Z7Q)}Bo6bs6FmA;(!X#<c{Ao<mNgkT`kHMd z+c@q_w6TbsI%6ASzR2_AJ)npqtMgLC_IQ5)_t<Bs)5ThBQ_EQaBPN2inZoyqFo!GP z=U|<g>uw3_>$K1TRjhp(yj;-oP1^gQsh5b_cj|8L&B6OuQ}K=%&vTkFk5k77h$Z|3 zeq(%wbCwS_yat-GNy%jTAkrVPt?}%77CQE&iAh4_whEEg+C`iY^IO34f~JACAGH4g z-fip4ko)?9G;zKk<)U9t`fpRG5c!6#Cm`oLHFn{Gczgltjyi--f~KJ^zU?Bk6n@Bc zqHO26HSecsQ8BHnU?B6#A9#eA)eW7rPiPBT_hpJnI}E$@>WCwE)=^btlea%<dmhTm zZw(OBFg24rkI0?H`jCD*=zl+h%vM9DV3bTF=pUUy<|fMAaLy>1b)fg1L5A@+WmCeo zZdFOz<_G;xl(|R?v5oW4#v;ADK-`jEgT2K1zOg$CgitQaDR$McKd|jvu1@&okElQW zF6;SqmQkB#+Le<m;}XyZ**0FYj2UMr!;Lc5B+96qDr${>2rOyrhn0n*wiz~%zGF^H zxLk;}rEb08eKluog$M7#p>GMF2+XA&GbR{)%_FAFC+$4Y48A*&7K$j9`Dw&A6lT^z zUITxM1<SNh+(~S{ft{ShPBO9dT~3`|Eg(P9z)VeI7;}?lF|9P5o8&3T$DbD=-}a?t z0yYTr{m777=DT-kS>!nGZMdJr{Q=zLxbMRKFzyfI{t@o5x$k-G%iI|Ok5K0KLD$FF z&l~gupwG()`~`WvG~rkFO-F&K^;chXvk)19&C@GGH)0;hgP$35BfrmqwsU0!-Zk|I zmoU;wLtese<a>!d#I}IV=cbpkO{gQ;R{1#Nb&K^m3jA`{Jq3AKi|yMW0{i1TtDlSS z%-r|cmfizu-jQbDnxTjGR-7wJ@xpE30CX$xgV7$y%lYUTi#<#$A}@h~J-?DXO)=8S zrf~^dk!Q@!@V{^yX+=y;$RXch;W3>o7rZu;hv!ta_=6g_S7PV6jkMw(m*`_t#C!qT zoszF5(n`tMBYe=dksn1Lg}qE0Wg)L2--NuJZy(G_jIUcw4BO-;DU1HabW#@i8<4*Z zV?@AC+KT5^b)j&qRiMYHx2^`hM|t>|WizdabCbSf%uVu`PWlH}#@r;2X+;z!<*F?_ zrjx#d+-1l=h&2Xnx6c!dzbW4wJ8GV|5Oi^d=famMb3=|PlQ&;JFU|*@Wyt(I1Lrbv zlajdeK>x(F$3AaQ1Fz2^W+k3Ed3fgJw@x<o8f|aR<GG-Hz;zRz38ZuGn`Gj4;Tb{N zz9KP66QXqj=+n%)*vlIWo+8dMpK*!u;@Eqi4}2Hu5>Z9#DdZKAKc0DyD40ds@k|jo z2KxLn=pCd?Lw=^U9)AT*j>&qg`%;ZbITpJP$7^Nz?-{zLX7(8Ns7Bd`K>G}3bBr=A z=gd6Q9{aQWKZ)5i#cYdnlWlPj^d*o{8wzU>7n;=K?kVsHbyf{%SK=AXcg?Ro8qece zN}oD<-Nw20kZP{$Og`7={pOnTzrb??6T$o6I`s5F57#9;`+n7wTZ|YKX)D3w+NuY# zJd-*OIXr8O^_ra*0$t#Iv<~qpj){B3wy+R6tv_cyMUFYA<h1?-d1K6g$8>UBAkTQ7 z<T1^DV9ayiZ83SOx-INq^}}i*)K>qP_6-dt-Qn04?)!jrM{C~)yEkkg-JDODRvRW~ zHt)e)3L2h!HS{UR`)U(+E$*UWVrKI$E#wg{@Wm`*eHJ}Tt1HK6Ha}_V$tEtL=Sqpg zoWrz%d&!0ak1@CA-y&uWUp5P|K!1(zt|R`3wS?Xy4Eyk5Nr3S;<vZxFnU!U<qe5U^ z0{UW0IZUfnlQNsbW;rE=342fuV{WqkOe-RLejW61KK&x{D;(HES38aJ`e2Lb5&_2C zDC7TbRY+(e;F0;OkzXzXjJf$ftBBS0<OVRF!{<RRtxF3zU)4hOUT@6(@h!begch5D ze!FV5dp~JQoZw;1uW||l!!+je&?@kDBaQb-lk`;?h?zEs%vE+8p53Ep4N3}}YT#C> zO6w!-nPu1D{fDjiX2UV=U_pJmbMj%NX_F7-I#5<UbU0Af0bo5&5%B6FQ0^9k9f;ZH z(LYy?_$Q~RC7kc#vrYv5gqVQgr)}_yPXykP`4;4F!1G_`QI_~M{Me;TV$98G4_yf` z%{kR*59D7ld7k|3)gIBlK}1A=F*jo@I5i`!Y&s{iZV%cI`R64M<AQ0fT@4=cIrCe> zPh0p*pT<vXseVlIp^NF{nhW`dkl%slCFg5CGvioWcJGYW-k4TptSz|)KBN{J>s_up zA8ZFN*W_W1b4Z<RtW(LW?*MPSMQ;3*q};S!;1yWp(nO}5iw}dxwQR*h@deGW#q&sf z0d2Vidp5>)us$tuqW^KfDCafq?SG+Q4&HcbL9u8_o{f3TcrZHb-9qP{eiScy2Y8(C z9_l(hZn4#%=ZvCnG4TgczV!^Q0dzZU`%pY@sOE*_w@0TYi&$5h*qe2Q;>y;<n~QK> za13+ram1ZIL;To>XNqF^_NWEl9es%XSqsi(R$w1Fg!2N$A!=K8X`!JB6?=B!?CXaQ zYoS%RzpskHfdcJ>4t~EwopnG}j}#%@t>(0@5XuqmRR<hnX1zTAVB3v<bl!KRD)#L{ zy6P?GeFKWvSLhJyH>x|^x-o`5_?9X09aC24smUYXF%8umG`?Tjh}e7<o<+y-T&jT| z{%PJx8$#M%XKjqwi#^Gpmad(MI7KbLxjKrv_+a0&7b&h|4h8jBJ0rIG4<r8PgAeeG zFDXR*{fel)SBSm7&Wc!<Dq>BYN^CRp=pXGWzah%%%!WOepdTB$_)V50zcW#n?38uc zgt}zI?xV1~7P3sUUhZEfz7rA|THw7gB73OjrQijNwe9>ytX$MZ-NXLv8`Eys17Ec1 z(TRa$jY^Ph=|6QzZy0e2?iKX$7qlL0tiX3)J&*pUMF-`nhw_FV=xAT8EXTXWSg$3% zRqDV#+kc_9y*yhCvfjNykFp%<e-8So`+3GmFqfQ~pv71Qzbz}z7lXbFwcZZYMYx*V zvKDJkM~yal-uV7)|Cix!d<#dP^IJGPw__(8oxuwpM?3_+^nkBI)`Na9Z8rKNeCxw^ za24V%tQE34`^2NsH{$Uf9g7qfzCVi<3iXJFzU3CMT@`zYA(lFb-2<$?P~m$iMqFIO zdV=jC^-0{Lz%dr|->6gjhNWfbGYg)^H(XX-)Lptjaa{%d_o3a+>EDWV$)nL<LiQx? zUFbgr*@&Ov>{ym#x93iy9HSoL`;k_)7TO7W(f^=-8)$tvpJw`Qq=k~cuw8X6q;Bff zGZOZfAqL%zbtC<!ImKT8Jos((kHh@tuVq|&l>SS8``1_%q%S@2<xtIU9`%XBL)pW( zZf80Dn0r{(YLq3*khYU2ZSfg)O*XLWkS-JjfAgJ0+#5do2YmJ(+W55Z4N)e`VxQ>4 zd!9p$2ZA2>XbAo8yVQm87g6#T>e%mlvbYY+!ui{y(W}6Vh=x+Xg;ot3`a#$y8Wwir zu3(Hr(0_&+yAA!+?S~Jk`(j{Ktof*qG_1*Y=;w{Jzx1Eve}(vl>`a-b&Mz4K^`&4h z?7jdtajf(~AIHaB13xvBdCuFi@8?5Cq${l)r$ZQrM=_rgKa6;wSS)Jz%wQdg&;~nI z=aD{)FOR#ojq>QbcZlNNHaUitxDOU=#hPIEE!xjLVoWFJhM}4lgW1r}GKVl<C&m!w z?nX7px%<5o<-Ct_nlZ<D+;6vSEPA_52+tji3vN{Ton&_BJ5v?cjTefVKE%#mgFI=k z<K9%{KB8gFlTO;p<eB|XewT<CpAoM%+Pu+=wtm@Y3%l*_o4)KgM_JDHIf{0pU-<3l z3dA>?Geqrf__PncG20+|=oH#y)0XX4S{G=tjov`IW#ZOMwyzi8VT$yv)wsjftj=dl zTqE0EP0VFF;_ZJ%9T;mKKsoieIPTdV+@A!2Ek;_#qU$WYUDRX7x49o_vGDG*$@N=! z9J`dO!hCZZ=&HE~VtGF`d9;PR77LH#U*J33D$Fm3!7Bo<0x=q_F``W-&k6c8TwYv! zcaXdWlgD~g;_87M_f6!jH+chi*Hx|=_&y$aYrvCzc!N`9ccag99ByVCAf~`P{Yu&j z(C$ThN<7Cl#~$0Y1bVFPwF+2)HdKYS$4Xyjwh!CxJ4jpGk>z+r!TcpAW;}F8#wyF@ zGbu7o)UGkxk@c*{rQ(w9h;!UzTeYKZ^iiG3p9fyoSj9y-Lm!^!8phyC<k?R2S&NCK zY%%b}%0AI=;hk%iGXNjo2D-Ivb4^|q=;T@3b|QF2+d}Rzc-FQ}H_IcR=OJG3W!oyI z9BrkY*0w!CKSRa|y1i|Oz~g-OxdZD5bFMs4?s$7AuJ>^n?N<{@t`Du>ri(1B6U}u} z`vg&Y^FM{_B*yLuM;g|PV>*Y;HKQBPpMIPjTi1;!&saD4T#0p)2kq96bLACSgB`>g zF)|VHuP3o@Ocy1-E2~1>w-rti>n}xnaNko8nz25^9tQ7*%vylG9ryEC3x&GUh8Mci z8%p0oeYsXT489LIf3BmoUUjq<{m~m!S1;I4nrH74#NKjR73}|*XBz9cku>&SzV_<G zx7nEQBnEW}d9XiI$T#H-no#GH_A9i<X>{xxM`INO`w+3**HRDnV<Kn58tm^_Z-Kq4 z5B1G<4nIRbD#m(o%E)>#<v0AV81t;NL}c#7-n|Ozo_1H&iAvb-&sAFS&H(1Y+|I*z zuYqe(5B%{hly?~K0qw)sJs_M%_JXc{7O$oM`ax^Nx~mI)66@huzQQ$BzVY5zE#!KD zWxiWgTQ5dF&*0}7{H4g_8G&a>UMF$o$g|AnV)4CQ1=`KTYYuVq?@$KUxdXV@g3mH} zXZgQHdgu&&@Pn~wL9D|P{SbZX7}g9r)_VDW6|UoW#`3xMIr`yA^vM`(6!4*H?q4*l z@lHUd4(s=R?Af?~`C#ltK@IW>a3gz+oHP7ZLc-6)Ziej=p97n@$2cU!KC7N@pg#Oo zzphOStq^%feuutH{yxy9EYDi7f7;9a5aKVj2QVI1PS#Fvtv%BI1)U!Qx6>g8`!LSf zmh|o2_$`L})%)8%M68SXKF5^KF0@HM@;--l^T)V%6^NVTYX0B?wB@7OqLwz@l#TsK zbyX-iz7TiWj6B<|AMJJ&`-Fzv?AE(K!5I6tH}(eg&GE(*q?Oer`;GLo=&K?-F^<49 z(&-o@RhgLz$CH&N@@AbzGscpd7#|Wxns6B7BPnYgb2fVo`$f)LAIGRwha7iS8sas^ zShUhMIY*bj>Fm)or)#vVHfa=YA?lcyVX3!ayJHm2Bb=l4{XcB}CFbjYwSIRJ3qNrV zVcR~6eXS2|TL;=bi<-lJ)SvT?$E8jXcZtB|X1lWOIFI@q!^z*8(9loZ7%y1U4fbJA z!Er`A3eEPXOd;n`)2GH9igY&UJI@xOZ(uCkh`q4256?s&W{mI8xaUAW`!vVSaoo8V zcjjv++A$Ur>j$ON|C(?W&ekxWXLb70u$TLMX)pIMs#C|hRj)42)?&@L>#)<8rUg}` zeOr{^d8ilo*k2^}0;~&u9VeQ2w!IYOzSxcZ(WX~~3(vDRu_iq2S#`{OR>2nI_f<6X zF~&IzoG~BgnDcQ~r`$_Zx9=b#xUf&h+}RABo<)h6MH9}ivtYxgsHcom{2l2U&={Zi z1ZnOOxCX}DxOZ<)YP<ZHw>mIym1ExGI)Hl~+O@Hzxy>lg8Y8jnzdi5^f6v8l+96{k zGF~!Nvp?ANqHqo2S<bndze%&>C1LEz^YOk6*8snK0nd8u$rU_X-1CfckC+?#M>n1i zKFHE%h2Z&0@vfLEj?{5nep!p%yCwfVp7-EI>$}k>H;A+Z-8chE*JAK7&QQ>%&j}aT zYz2tyI@+~Z*FNF$p<T(V3nh4@3zPm!=!?%4*o&iWvt9_laWcN6d;ZU=%iZp^Xzyx~ zy|VzmEYtP~R|U=iu;wf)7e(M<4#w}(P;dW(N<cY;HIkccmWU~6V)&Uj)-DmOO(N*S zC73t)Oj?feW+7;OcbW*ig7%^uV|ZNWMoz`|vhR_$segQ6bKQi%Ht?FzXMOALtR_#) zd3b}O;rDg6qz7;8pAhgNHsluVVfGE*c=YX0<F2MH*)x4-qwK#SjrQ_oA~yHZKV80D z=(!dCD8O@F$9<}Z=^Jn_LVsC@`*h^Lhx;tx>T#a~9lp5BHy`}fxR-+e8{EH)wtEWq z3!#_wy;p?rjIZ{!iIC{R{Q<_SaPJiOZ6VyB1YN~_4{YgI17Am-xc4*aia6%wMm{H* zztqU*8tVXJme2>+WR$s)_IuTU{~{6dQ*T{HnQtAg%(KcO_)f^*l2PWT9l2+f3882D zw`G)dIFT<nt4s&JX$`PbfqhWSYub=e)^ukEa9UYY(OG5eQ~o<L%CvLvJ`3CQHnb`F z1p7++F8Bg{s6BW1*~kSrD@S{)=yMuq0<^y0D*@m3j6e_YIU{w+R8Y5E<o)0o^+o<H z<oi%}K6^3$gvYUNnBUm<{4J9L#@WS_$YX!S_3G=Giy0#jS;Noz=3^~dlo{~NQ4RiY zOrARvyo<cC%{`fc8*zr=^Qt`0??hXKUy$;XhM(QnA_520+#{YiV$?ka0f~9q#6%`0 zFnG7Zz=+Hj!kc!T71)e-1$=vym_7|-B=d#nTLSTD2hNcYw->rI@CW4aK4T((moxA> z@`!I@t!TC}_J)+{N~`ECV!N$zgt{`Tdi6B)o7^S6*h7c93NGr^G2eGhy|`D;#J%W} zUOgB0>6iBE1-Q>&+N)2+z4Y>4y$JU&FYDE(<L+JFtIxvy>gry74(@Bd)q7~&w|f=z zH~s3gnL^xNjq$M|&AknwOMLftFFdP`o$0HD+(qb*7k|B1{~GR>L4FzTSJd=kl!bh2 zzuDW^`0ZYO-GrGM#yy@<>-qapn3*T(YQ{_fKE_T+G=8U7zY+KHrM>xARrd-!GxNs+ zQ+L)(#;>pzt={YvfdQn|^z501&YYR*Ex9x6KreLW%~WqMn5iOeQuv3-Gu6L{P+dz# zpl|@?f2PFfU;iv;$a5E;2WhRoC}`v0zv<4zIGgW8{8)>nJ*34jh67#fk7I_PA?<^D zCBWz1!8?VkWqI5Me}vQaW8TyBYU0?Z#^T}omN_p`Mk&Tz1sON^Z@n9TmhCq>?)Iv& zN6>#PT=nSJ9~kiq=!I|98_uoiaQC!fZE}aFxTnp(+Pw(=2oxf2%RcvI%y)c_4`BQp z!`z4%;4FR<;JID6#^4zc*(zM^DEkkb7t^(1kyGFqjl00SCNP&f5EH<eLp#crzj?-U zhaB*5E_0+E@hH~o_#MK9x4~Rbw}>}=8?>^0sGF{e1+3#|sGom4o)h`-8S)y+6R?T2 zx&pi><3>4Y-eJ${n|giVah&2kv>kT;98j~5D0t6}^-gt;fOD|U$Zf*)7wnHuO)MP# z1p5^OJGNq&^}w?ObEGnhY1A#my9cp6&~LWTZzg>O*EFt*6B?d5k3b)3UYxH~V13Yw z_qdp68tZE#Eu39flg4uUId{N6c=rx56YM*&&(x5QFpoZX%CyId#ky*T;&d3eLpB^^ zg)(L}4R!Cq#d(r(4Yo;cKE6%;f*yVb`2}w5Ew%{PsVouu=mcYIxt%hOK$+izhJEuL zg-+*S1a;HV9@g(-He$`_=b905=Tlic2S~&Liy<pxC)V=cz&8^zX5;}zAnyNe3~O1$ z+L?a`X_4;j^<nOpYdWr%N^lNhJb&5Wv8DsI`t1hc+JU-r4EzH3E+I<WZT4|bCV+!~ zjrpMib?{-Xlxw-iz{h%ay`A1h`V72($+Zo}xK4kgZ79b)W3`C6<w-qkOV*2VE!w#o z^-#s6`5ddH-G#hNKY(<5ylElxec-hb+mMwh^FK7P9?Lm~Zqj%j0hy=@Up0c}UeEQC zR_1n!uk-sK&Vje1j?_i}<>Nb!a@3>QLc8B+12cAxy>~5i9)(V>{n{`Gv5(-{(aE*p zJBa`B_X_XJ!FdPfffK-Gq0JWJ{yh2*f5$NKtjscglWoy;!ZiiwBFC^FuYr9Wx7PCz zEA}$8PV~XIkhY(NRDve)Uq@O~(o6ds1$ZuJbzY9VPb?~BdNul}aUO#6h*Hd#?G9Jz z6ytn@-&;&E@biE_lP$!|Fv?2kE~RdD(L$edMycl-;c~;j0%xG?C*#h-`*ZXs<}o+= zpd0JUOqOZ(J9)lvKh9@7C*rm5qK~L6u`Y!UuI1a&pV%JlV{k`XRUofnJ*07+in?5n ze%6it#c}9G`ZdV=#?3JL3dhGp*hU=FH9p~*fIQ0{0PQejdWsXzkuft8&k-Shy`f!T z&jd^a^G^rvJSXBA(KO8G97jIz-QUIjONddw8Oh&~9I8pgLS$RuJFy*wPA%#`8pjzy z;{52Zpmiyu{T>G0?sxiI%Do1@JY)JJu{iIN`L~c~3|i(7AkVt*N8Q(=-uf7^PwM#{ zdH<NWFduzS(hh=_%BCkkr_ZeY(rVLg@THEYk#_%m;zIXWQJOv6w4LKmo|$nRwpn!P z7&~tGl6>N5D=`6J?m|0qPK-Dv8{ZMtVJs=gPr>{DKSo_-9d`h$;vGwwZ$X|i#4^Uq z`JA%1PzL)!)}s&4X%%OKJe$!_KFgg3zWaE5Zy)wH_)W?qK8%0%Nq%F1wa;J&#tP-h zbAK4GeG>LbpU6IJ;Eu&>xtF)@S^2D6iT!&7`}e1p3gdT6ee`DrY=CX_K}(B<7*iI0 zlW64Kfg#7wvF@<O-gu@qa&|2D%Zw4o{W8;ho*8QioON|E9(bv6aei8e`R*v<fX7n2 zyU>I3IVM!gy9<7dwYZ9Rr?E!FzICu4_i~}G;h1E3Sf30U?-0PwW}BV%bFKsyu}o8k z4!<e|diZJRX;wvydj0|1StslJ35*3uU;42B_n;2th~sK}Hv#^<!25siPcdHX<r<Cg zkfVs7(ziGVbaB2vj`dEg(ZP2KW_6)W8(?1yaY$?1a=pU%!~o`-W-~@1V0$<4GS(SE z-%74a8!K@>c+gmrS}{KOhOwH@;1hqR7CNlv%xV&zHC^bdR-6W(5;KglJb15}af^L; zSN<6AIao9D-4T5};;3jx9qpzdHWER<U_TVV@@#r9_U-;XS_m=f!IsR56Eo3X{MI3^ zHbr%uNpzr0t1M&G>?_pk!y1xvJ@?3e0iE_(V@!<YpzZe7l>Fbf9s3T~KkXO?Z_P^` zJCZRixB1M{;Fo_Trq%VOL`)0*H)2{`WAGV)xhL_Az}<*zzz@FdxDY2`?BZ+xjPLL> z&VhIc_sdz3TMQcG{c=qAAuY!=eJd<~T86sJGu+fW9?wxN!@10JbPGNmXF7eE=hItz zok)uTaRuf@(3E9Pp|q-t)0dU&%HXSb4wq{f%cx_A$S(yZ)}j{<cR5xZDs(&EZWb=m zLM>f|`$=m?-H<P<5b32Yk-`Sj&_}-7C+02G#m>ckF{4yC^{?vUfyGh>^Z3@{30;&w zA!&|}Z`n?{a^W1*W}uIt{AS_!eLde@)RZ@UqUCWP@Obxs5bu_tZ(W#_|3G}@?cJx& zTev$zWFBxazK1m?%J89#`hg#8_X+h0pKv@ueb}eHSufN8>oRTAgtzO35|BE5LI6j* zMsyQ*ARFrni%zMpK63MRtImWz75Y@u#>LR})zkECLz}<i{!PILD7RdUIdXV7Ui+a_ zytzt@ZDn0MgyYC=G5wBqj30ZQ4`beF7GqF{u}2;RKT+P;R_1rXC%CunM_+IYJytB# z)-kwNpe@J2_7!Mbyhl}gDax8YMGIc*oVV~NB~8H~+Gj>_MevT<TY~AuO0aYGg~7Bb zBKUYoc~G{^3bz=<`<AuSF&F$uUoo79KJkd9Pax!43SQ_(T`Ts37kb3(8!FDWF8#cs z7re3`eY#@NjMdjJ0>3PM^~^<&d|J3j>Sy`0W_yFPODcnRF5VK{n$cv~Kzqi|R)ZNO zj^LAvFAP4Ek+5l8hPIvkWp;^%eapDtd&Ric=~F6z6Tun9Ug)ZXu7g3ZrVd_<ess+g zB}o42V%6ZUne8wz*OhEd;LxZ3g8A#t#kT~B-8SV`1ABY%mLRcr%x(%^SK@>Xi-QkO z`D*ad;tS!Yge?xC{GPt8)4eCWSiilD*f{-8|33&j>Eo^FcV1lErZgFTrQSPc-x~Z$ z$>+h{22UOQG3;btdw5DY%5O5tAg*)vR}JjrB`+9wuW9R?#g(w79QE=VSo)CIS+g~i zu{e14Vh4Pv8f`j$wlLaKn1B6_!cK=v3szw4dJuCcN1xL~)d|LW*e2*dVcu)RI=lkA z9D(QS#U@<!xUNI~dQdir^QF2`cST8%_U(Oo&r_Hj&<~8iSMPph%s<vFuL?B0c0<kP z7Xv@8_@AL?``*2DcW=pz>z|yfJoWl>)4kWfHR*+qg#OCn+nWRHt{PYV{qUqa%S8L{ zuHEpJZ+!aLdHbK5zEr<t)6W(@x9k1T{9kl@;ql%{ZC?_1ombv{`Ew;tj8U)8_TDq+ z^7gVjzZhEWOOz|`iQNDH|EQw44OhgMxR!a(pJy#)?&|BmziO_3!^*jJo3FiY<=j;( z*Uq2oHIfzIUwQfUD>q-aYWdpl&8=RtbV)_ck`)(MRxX%ZQBhraNomR4(-1Z5Zm4Ql rH8*ive*K0`=g+NL;{C?OR?3`}*Ij2VJw+OJx<OvuenUHMqyGLEKGshA
literal 30272 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 M`jeg~&jy9~zoS<a>;M1&
On Tue, Jun 27, 2017 at 01:21:44PM +0000, Ard Biesheuvel wrote:
Update binary AmdModulePkg component to new versions built using the GCC5 toolchain profile using GCC 6.2.0.
The following source code changes are incorporated into this build as well
e8d5cf37d2cd AmdModulePkg: bring .DSC up to date with recent EDK2 changes bdfcb308553b AmdModulePkg/Gionb: avoid hang in reconfigure routine
Source changes reviewed as well.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org
Reviewed-by: Leif Lindholm leif.lindholm@linaro.org
Platforms/AMD/Styx/Binary/AmdModulePkg/Gionb/Gionb.efi | Bin 43296 -> 36768 bytes Platforms/AMD/Styx/Binary/AmdModulePkg/Gionb/Gionb.inf | 14 ++++++-------- Platforms/AMD/Styx/Binary/AmdModulePkg/Iscp/IscpDxe.efi | Bin 262144 -> 262144 bytes Platforms/AMD/Styx/Binary/AmdModulePkg/Iscp/IscpPei.efi | Bin 10336 -> 6976 bytes Platforms/AMD/Styx/Binary/AmdModulePkg/SnpDxe/SnpDxePort0.efi | Bin 30272 -> 24992 bytes Platforms/AMD/Styx/Binary/AmdModulePkg/SnpDxe/SnpDxePort1.efi | Bin 30272 -> 24992 bytes 6 files changed, 6 insertions(+), 8 deletions(-)
This implements a UEFI Shell application that updates the EFI NOR partition with the contents of STYX_EFI.Fv. Note that this means that a) EFI variables are preserved, and b) this updater can only be used on systems that have already been flashed with a firmware build based on this open source branch (and not on systems still running AMI firmware)
In order for the flasher to have access to the various PCDs that describe where STYX_EFI.Fv lives in the NOR, it needs to be built as part of the platform, but after STYX_EFI.Fv has been generated, which results in a chicken-and-egg situation. Therefore, the recommended way of generating the flasher is
1) delete the Build/<platform> directory entirely 2) build the platform 3) build the platform again, but with -D DO_FLASHER=TRUE appended
The flasher application is called 'StyxFlashUefi'
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org --- Platforms/AMD/Styx/Applications/StyxFlashUefi/Scripts/GccBase.lds | 86 ++++++++++++++++++ Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashImage.S | 25 +++++ Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.c | 96 ++++++++++++++++++++ Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf | 53 +++++++++++ Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc | 12 ++- Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc | 8 ++ Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc | 8 ++ 7 files changed, 286 insertions(+), 2 deletions(-)
diff --git a/Platforms/AMD/Styx/Applications/StyxFlashUefi/Scripts/GccBase.lds b/Platforms/AMD/Styx/Applications/StyxFlashUefi/Scripts/GccBase.lds new file mode 100644 index 000000000000..7a0c87c6e32b --- /dev/null +++ b/Platforms/AMD/Styx/Applications/StyxFlashUefi/Scripts/GccBase.lds @@ -0,0 +1,86 @@ +/** @file + + Unified linker script for GCC based builds + + Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR> + Copyright (c) 2015 - 2017, Linaro Ltd. All rights reserved.<BR> + (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR> + + This program and the accompanying materials are licensed and made available under + the terms and conditions of the BSD License that accompanies this distribution. + The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +SECTIONS { + + /* + * The PE/COFF binary consists of DOS and PE/COFF headers, and a sequence of + * section headers adding up to PECOFF_HEADER_SIZE bytes (which differs + * between 32-bit and 64-bit builds). The actual start of the .text section + * will be rounded up based on its actual alignment. + */ + . = PECOFF_HEADER_SIZE; + + .text : ALIGN(CONSTANT(COMMONPAGESIZE)) { + *(.text .text.* .stub .gnu.linkonce.t.*) + *(.rodata .rodata.* .gnu.linkonce.r.*) + *(.got .got.*) + + /* + * The contents of AutoGen.c files are mostly constant from the POV of the + * program, but most of it ends up in .data or .bss by default since few of + * the variable definitions that get emitted are declared as CONST. + * Unfortunately, we cannot pull it into the .text section entirely, since + * patchable PCDs are also emitted here, but we can at least move all of the + * emitted GUIDs here. + */ + *:AutoGen.obj(.data.g*Guid) + } + + /* + * The alignment of the .data section should be less than or equal to the + * alignment of the .text section. This ensures that the relative offset + * between these sections is the same in the ELF and the PE/COFF versions of + * this binary. + */ + .data ALIGN(ALIGNOF(.text)) : ALIGN(CONSTANT(COMMONPAGESIZE)) { + *(.data .data.* .gnu.linkonce.d.*) + *(.bss .bss.*) + *(.payload) + } + + .eh_frame ALIGN(CONSTANT(COMMONPAGESIZE)) : { + KEEP (*(.eh_frame)) + } + + .rela (INFO) : { + *(.rela .rela.*) + } + + .hii : ALIGN(CONSTANT(COMMONPAGESIZE)) { + KEEP (*(.hii)) + } + + /* + * Retain the GNU build id but in a non-allocatable section so GenFw + * does not copy it into the PE/COFF image. + */ + .build-id (INFO) : { *(.note.gnu.build-id) } + + /DISCARD/ : { + *(.note.GNU-stack) + *(.gnu_debuglink) + *(.interp) + *(.dynsym) + *(.dynstr) + *(.dynamic) + *(.hash .gnu.hash) + *(.comment) + *(COMMON) + } +} diff --git a/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashImage.S b/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashImage.S new file mode 100644 index 000000000000..041339ee9b47 --- /dev/null +++ b/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashImage.S @@ -0,0 +1,25 @@ +/** @file + + Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR> + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + + .section ".payload" + .align 12 + +ASM_GLOBAL ASM_PFX(StyxFlashImageStart) +ASM_PFX(StyxFlashImageStart): + .incbin "STYX_EFI.Fv" + + .align 2 +ASM_GLOBAL ASM_PFX(StyxFlashImageSize) +ASM_PFX(StyxFlashImageSize): + .long . - ASM_PFX(StyxFlashImageStart) diff --git a/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.c b/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.c new file mode 100644 index 000000000000..a7bdbffab891 --- /dev/null +++ b/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.c @@ -0,0 +1,96 @@ +/** @file + + Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR> + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include <Uefi.h> +#include <Library/BaseMemoryLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiLib.h> +#include <Library/ShellCEntryLib.h> + +#include <Protocol/AmdIscpDxeProtocol.h> + +#define UEFI_IMAGE_OFFSET FixedPcdGet64 (PcdFvBaseAddress) - FixedPcdGet64 (PcdFdBaseAddress) +#define BLOCK_SIZE SIZE_64KB + +STATIC AMD_ISCP_DXE_PROTOCOL *mIscpDxeProtocol; +STATIC UINT8 Buffer[BLOCK_SIZE]; + +extern CONST UINT8 StyxFlashImageStart[]; +extern CONST UINT32 StyxFlashImageSize; + +/*** + Main entrypoint + + Establishes the main structure of the application. + + @retval 0 The application exited normally. + @retval Other An error occurred. +***/ +INTN +EFIAPI +ShellAppMain ( + IN UINTN Argc, + IN CHAR16 **Argv + ) +{ + EFI_STATUS Status; + UINTN Index; + INTN Remaining; + + Print(L"StyxFlashUefi: firmware updater for AMD Seattle based boards.\n"); + + Status = gBS->LocateProtocol (&gAmdIscpDxeProtocolGuid, NULL, + (VOID **)&mIscpDxeProtocol); + if (EFI_ERROR (Status)) { + Print(L"Failed to locate ISCP communication protocol, terminating...\n"); + return (INTN)Status; + } + + Index = 0; + Remaining = StyxFlashImageSize; + do { + Status = mIscpDxeProtocol->AmdExecuteEraseFvBlockDxe ( + mIscpDxeProtocol, + UEFI_IMAGE_OFFSET + Index * BLOCK_SIZE, + BLOCK_SIZE); + if (EFI_ERROR (Status)) { + Print(L"Erase failed!\n"); + return (INTN)Status; + } + + CopyMem (Buffer, StyxFlashImageStart + Index * BLOCK_SIZE, + MIN (Remaining, BLOCK_SIZE)); + + Status = mIscpDxeProtocol->AmdExecuteUpdateFvBlockDxe ( + mIscpDxeProtocol, + UEFI_IMAGE_OFFSET + Index * BLOCK_SIZE, + Buffer, + MIN (Remaining, BLOCK_SIZE)); + + if (EFI_ERROR (Status)) { + Print(L"Update failed!\n"); + return (INTN)Status; + } + + Remaining -= BLOCK_SIZE; + Index++; + + Print(L"Block %d of %d updated\n", Index, StyxFlashImageSize / BLOCK_SIZE); + + } while (Remaining > 0); + + Print(L"\nDone!\n"); + + return 0; +} diff --git a/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf b/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf new file mode 100644 index 000000000000..2ad7c1b98ef1 --- /dev/null +++ b/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf @@ -0,0 +1,53 @@ +#/** @file +# +# Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR> +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#**/ + +[Defines] + INF_VERSION = 0x00010006 + BASE_NAME = StyxFlashUefi + FILE_GUID = 07b65d9d-b1a2-416e-bd04-0b61b775f924 + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 0.1 + ENTRY_POINT = ShellCEntryLib + +# +# VALID_ARCHITECTURES = AARCH64 +# + +[Sources] + StyxFlashImage.S + StyxFlashUefi.c + +[Packages] + AmdModulePkg/AmdModulePkg.dec + ArmPkg/ArmPkg.dec + MdePkg/MdePkg.dec + ShellPkg/ShellPkg.dec + +[LibraryClasses] + BaseMemoryLib + UefiBootServicesTableLib + UefiLib + ShellCEntryLib + +[Protocols] + gAmdIscpDxeProtocolGuid + +[FixedPcd] + gArmTokenSpaceGuid.PcdFdBaseAddress + gArmTokenSpaceGuid.PcdFvBaseAddress + +[BuildOptions] + *_*_*_CC_FLAGS = -mcmodel=small + *_*_*_DLINK_FLAGS = -z common-page-size=0x1000 -Wl,-T,$(MODULE_DIR)/Scripts/GccBase.lds + *_*_*_PLATFORM_FLAGS = -I$(BIN_DIR)/../FV diff --git a/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc b/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc index 091914c047a3..90cda24ae49d 100644 --- a/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc +++ b/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc @@ -17,8 +17,9 @@ ################################################################################ [Defines]
-DEFINE NUM_CORES = 4 -DEFINE DO_KCS = 0 +DEFINE NUM_CORES = 4 +DEFINE DO_KCS = 0 +DEFINE DO_FLASHER = FALSE
PLATFORM_NAME = Cello PLATFORM_GUID = 77861b3e-74b0-4ff3-8d18-c5ba5803e1bf @@ -690,3 +691,10 @@ DEFINE DO_KCS = 0 !ifdef $(RENESAS_XHCI_FW_DIR) OpenPlatformPkg/Drivers/Xhci/RenesasFirmwarePD720202/RenesasFirmwarePD720202.inf !endif + +!if $(DO_FLASHER) == TRUE + OpenPlatformPkg/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf { + <LibraryClasses> + ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf + } +!endif diff --git a/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc b/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc index 57d1425b2c8f..5b7d7f4a7b4a 100644 --- a/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc +++ b/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc @@ -21,6 +21,7 @@ DEFINE NUM_CORES = 4 DEFINE DO_PSCI = 1 DEFINE DO_ISCP = 1 DEFINE DO_KCS = 1 +DEFINE DO_FLASHER = FALSE
PLATFORM_NAME = Overdrive1000 PLATFORM_GUID = 36774DD7-20DE-4C5B-8722-f8861DFF1F16 @@ -701,3 +702,10 @@ DEFINE DO_KCS = 1 gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000 } + +!if $(DO_FLASHER) == TRUE + OpenPlatformPkg/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf { + <LibraryClasses> + ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf + } +!endif diff --git a/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc b/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc index 6c284fb3b7db..662a15a9ccea 100644 --- a/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc +++ b/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc @@ -22,6 +22,7 @@ DEFINE NUM_CORES = 8 DEFINE DO_PSCI = 1 DEFINE DO_ISCP = 1 DEFINE DO_KCS = 1 +DEFINE DO_FLASHER = FALSE
PLATFORM_NAME = Overdrive PLATFORM_GUID = B2296C02-9DA1-4CD1-BD48-4D4F0F1276EB @@ -752,3 +753,10 @@ DEFINE DO_KCS = 1 gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000 } + +!if $(DO_FLASHER) == TRUE + OpenPlatformPkg/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf { + <LibraryClasses> + ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf + } +!endif
On Tue, Jun 27, 2017 at 01:21:45PM +0000, Ard Biesheuvel wrote:
This implements a UEFI Shell application that updates the EFI NOR
standalone UEFI Shell application
partition with the contents of STYX_EFI.Fv. Note that this means that a) EFI variables are preserved, and b) this updater can only be used on systems that have already been flashed with a firmware build based on this open source branch (and not on systems still running AMI firmware)
In order for the flasher to have access to the various PCDs that describe where STYX_EFI.Fv lives in the NOR, it needs to be built as part of the platform, but after STYX_EFI.Fv has been generated, which results in a chicken-and-egg situation. Therefore, the recommended way of generating the flasher is
- delete the Build/<platform> directory entirely
- build the platform
- build the platform again, but with -D DO_FLASHER=TRUE appended
Build with -m .../StyxFlashUefi.inf instead of rebuilding the whole platform?
The flasher application is called 'StyxFlashUefi'
Only style comments below, but one silly question before that: Is there some particular reason why the application embeds the FV instead of reading it from a filesystem? Or just that you figured it's small enough that it doesn't matter?
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org
Platforms/AMD/Styx/Applications/StyxFlashUefi/Scripts/GccBase.lds | 86 ++++++++++++++++++ Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashImage.S | 25 +++++ Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.c | 96 ++++++++++++++++++++ Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf | 53 +++++++++++ Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc | 12 ++- Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc | 8 ++ Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc | 8 ++ 7 files changed, 286 insertions(+), 2 deletions(-)
diff --git a/Platforms/AMD/Styx/Applications/StyxFlashUefi/Scripts/GccBase.lds b/Platforms/AMD/Styx/Applications/StyxFlashUefi/Scripts/GccBase.lds new file mode 100644 index 000000000000..7a0c87c6e32b --- /dev/null +++ b/Platforms/AMD/Styx/Applications/StyxFlashUefi/Scripts/GccBase.lds @@ -0,0 +1,86 @@ +/** @file
- Unified linker script for GCC based builds
- Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
- Copyright (c) 2015 - 2017, Linaro Ltd. All rights reserved.<BR>
- (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
- This program and the accompanying materials are licensed and made available under
- the terms and conditions of the BSD License that accompanies this distribution.
- The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php.
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+SECTIONS {
- /*
- The PE/COFF binary consists of DOS and PE/COFF headers, and a sequence of
- section headers adding up to PECOFF_HEADER_SIZE bytes (which differs
- between 32-bit and 64-bit builds). The actual start of the .text section
- will be rounded up based on its actual alignment.
- */
- . = PECOFF_HEADER_SIZE;
- .text : ALIGN(CONSTANT(COMMONPAGESIZE)) {
- *(.text .text.* .stub .gnu.linkonce.t.*)
- *(.rodata .rodata.* .gnu.linkonce.r.*)
- *(.got .got.*)
- /*
* The contents of AutoGen.c files are mostly constant from the POV of the
* program, but most of it ends up in .data or .bss by default since few of
* the variable definitions that get emitted are declared as CONST.
* Unfortunately, we cannot pull it into the .text section entirely, since
* patchable PCDs are also emitted here, but we can at least move all of the
* emitted GUIDs here.
*/
- *:AutoGen.obj(.data.g*Guid)
- }
- /*
- The alignment of the .data section should be less than or equal to the
- alignment of the .text section. This ensures that the relative offset
- between these sections is the same in the ELF and the PE/COFF versions of
- this binary.
- */
- .data ALIGN(ALIGNOF(.text)) : ALIGN(CONSTANT(COMMONPAGESIZE)) {
- *(.data .data.* .gnu.linkonce.d.*)
- *(.bss .bss.*)
- *(.payload)
- }
- .eh_frame ALIGN(CONSTANT(COMMONPAGESIZE)) : {
- KEEP (*(.eh_frame))
- }
- .rela (INFO) : {
- *(.rela .rela.*)
- }
- .hii : ALIGN(CONSTANT(COMMONPAGESIZE)) {
- KEEP (*(.hii))
- }
- /*
- Retain the GNU build id but in a non-allocatable section so GenFw
- does not copy it into the PE/COFF image.
- */
- .build-id (INFO) : { *(.note.gnu.build-id) }
- /DISCARD/ : {
- *(.note.GNU-stack)
- *(.gnu_debuglink)
- *(.interp)
- *(.dynsym)
- *(.dynstr)
- *(.dynamic)
- *(.hash .gnu.hash)
- *(.comment)
- *(COMMON)
- }
+} diff --git a/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashImage.S b/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashImage.S new file mode 100644 index 000000000000..041339ee9b47 --- /dev/null +++ b/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashImage.S @@ -0,0 +1,25 @@ +/** @file
- Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR>
- This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD License
- which accompanies this distribution. The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
- .section ".payload"
- .align 12
+ASM_GLOBAL ASM_PFX(StyxFlashImageStart) +ASM_PFX(StyxFlashImageStart):
- .incbin "STYX_EFI.Fv"
- .align 2
+ASM_GLOBAL ASM_PFX(StyxFlashImageSize) +ASM_PFX(StyxFlashImageSize):
- .long . - ASM_PFX(StyxFlashImageStart)
diff --git a/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.c b/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.c new file mode 100644 index 000000000000..a7bdbffab891 --- /dev/null +++ b/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.c @@ -0,0 +1,96 @@ +/** @file
- Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR>
- This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD License
- which accompanies this distribution. The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <Uefi.h> +#include <Library/BaseMemoryLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiLib.h> +#include <Library/ShellCEntryLib.h>
Inconsistent whitespace. Not sorted.
+#include <Protocol/AmdIscpDxeProtocol.h>
+#define UEFI_IMAGE_OFFSET FixedPcdGet64 (PcdFvBaseAddress) - FixedPcdGet64 (PcdFdBaseAddress) +#define BLOCK_SIZE SIZE_64KB
+STATIC AMD_ISCP_DXE_PROTOCOL *mIscpDxeProtocol; +STATIC UINT8 Buffer[BLOCK_SIZE];
+extern CONST UINT8 StyxFlashImageStart[]; +extern CONST UINT32 StyxFlashImageSize;
+/***
- Main entrypoint
- Establishes the main structure of the application.
- @retval 0 The application exited normally.
- @retval Other An error occurred.
+***/ +INTN +EFIAPI +ShellAppMain (
- IN UINTN Argc,
- IN CHAR16 **Argv
- )
+{
- EFI_STATUS Status;
- UINTN Index;
- INTN Remaining;
- Print(L"StyxFlashUefi: firmware updater for AMD Seattle based boards.\n");
Space after "Print". (Actually, this seems consistent on all Print statement in this function, and nothing else.)
- Status = gBS->LocateProtocol (&gAmdIscpDxeProtocolGuid, NULL,
(VOID **)&mIscpDxeProtocol);
- if (EFI_ERROR (Status)) {
- Print(L"Failed to locate ISCP communication protocol, terminating...\n");
- return (INTN)Status;
- }
- Index = 0;
- Remaining = StyxFlashImageSize;
- do {
- Status = mIscpDxeProtocol->AmdExecuteEraseFvBlockDxe (
mIscpDxeProtocol,
UEFI_IMAGE_OFFSET + Index * BLOCK_SIZE,
BLOCK_SIZE);
- if (EFI_ERROR (Status)) {
Print(L"Erase failed!\n");
return (INTN)Status;
- }
- CopyMem (Buffer, StyxFlashImageStart + Index * BLOCK_SIZE,
MIN (Remaining, BLOCK_SIZE));
- Status = mIscpDxeProtocol->AmdExecuteUpdateFvBlockDxe (
mIscpDxeProtocol,
UEFI_IMAGE_OFFSET + Index * BLOCK_SIZE,
Buffer,
MIN (Remaining, BLOCK_SIZE));
- if (EFI_ERROR (Status)) {
Print(L"Update failed!\n");
return (INTN)Status;
- }
- Remaining -= BLOCK_SIZE;
- Index++;
- Print(L"Block %d of %d updated\n", Index, StyxFlashImageSize / BLOCK_SIZE);
- } while (Remaining > 0);
- Print(L"\nDone!\n");
- return 0;
+} diff --git a/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf b/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf new file mode 100644 index 000000000000..2ad7c1b98ef1 --- /dev/null +++ b/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf @@ -0,0 +1,53 @@ +#/** @file +# +# Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR> +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#**/
+[Defines]
- INF_VERSION = 0x00010006
Not 1.25?
- BASE_NAME = StyxFlashUefi
- FILE_GUID = 07b65d9d-b1a2-416e-bd04-0b61b775f924
- MODULE_TYPE = UEFI_APPLICATION
- VERSION_STRING = 0.1
- ENTRY_POINT = ShellCEntryLib
+# +# VALID_ARCHITECTURES = AARCH64 +#
+[Sources]
- StyxFlashImage.S
- StyxFlashUefi.c
+[Packages]
- AmdModulePkg/AmdModulePkg.dec
- ArmPkg/ArmPkg.dec
- MdePkg/MdePkg.dec
- ShellPkg/ShellPkg.dec
+[LibraryClasses]
- BaseMemoryLib
- UefiBootServicesTableLib
- UefiLib
- ShellCEntryLib
+[Protocols]
- gAmdIscpDxeProtocolGuid
+[FixedPcd]
- gArmTokenSpaceGuid.PcdFdBaseAddress
- gArmTokenSpaceGuid.PcdFvBaseAddress
+[BuildOptions]
- *_*_*_CC_FLAGS = -mcmodel=small
- *_*_*_DLINK_FLAGS = -z common-page-size=0x1000 -Wl,-T,$(MODULE_DIR)/Scripts/GccBase.lds
- *_*_*_PLATFORM_FLAGS = -I$(BIN_DIR)/../FV
Ah, _that's_ how you find STYX_EFI.Fv? :)
diff --git a/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc b/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc index 091914c047a3..90cda24ae49d 100644 --- a/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc +++ b/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc @@ -17,8 +17,9 @@ ################################################################################ [Defines] -DEFINE NUM_CORES = 4 -DEFINE DO_KCS = 0 +DEFINE NUM_CORES = 4 +DEFINE DO_KCS = 0 +DEFINE DO_FLASHER = FALSE PLATFORM_NAME = Cello PLATFORM_GUID = 77861b3e-74b0-4ff3-8d18-c5ba5803e1bf @@ -690,3 +691,10 @@ DEFINE DO_KCS = 0 !ifdef $(RENESAS_XHCI_FW_DIR) OpenPlatformPkg/Drivers/Xhci/RenesasFirmwarePD720202/RenesasFirmwarePD720202.inf !endif
+!if $(DO_FLASHER) == TRUE
- OpenPlatformPkg/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf {
<LibraryClasses>
ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf
- }
+!endif diff --git a/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc b/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc index 57d1425b2c8f..5b7d7f4a7b4a 100644 --- a/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc +++ b/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc @@ -21,6 +21,7 @@ DEFINE NUM_CORES = 4 DEFINE DO_PSCI = 1 DEFINE DO_ISCP = 1 DEFINE DO_KCS = 1 +DEFINE DO_FLASHER = FALSE PLATFORM_NAME = Overdrive1000 PLATFORM_GUID = 36774DD7-20DE-4C5B-8722-f8861DFF1F16 @@ -701,3 +702,10 @@ DEFINE DO_KCS = 1 gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000 }
+!if $(DO_FLASHER) == TRUE
- OpenPlatformPkg/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf {
<LibraryClasses>
ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf
- }
+!endif diff --git a/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc b/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc index 6c284fb3b7db..662a15a9ccea 100644 --- a/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc +++ b/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc @@ -22,6 +22,7 @@ DEFINE NUM_CORES = 8 DEFINE DO_PSCI = 1 DEFINE DO_ISCP = 1 DEFINE DO_KCS = 1 +DEFINE DO_FLASHER = FALSE PLATFORM_NAME = Overdrive PLATFORM_GUID = B2296C02-9DA1-4CD1-BD48-4D4F0F1276EB @@ -752,3 +753,10 @@ DEFINE DO_KCS = 1 gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000 }
+!if $(DO_FLASHER) == TRUE
- OpenPlatformPkg/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf {
<LibraryClasses>
ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf
- }
+!endif
2.9.3
On 27 June 2017 at 16:33, Leif Lindholm leif.lindholm@linaro.org wrote:
On Tue, Jun 27, 2017 at 01:21:45PM +0000, Ard Biesheuvel wrote:
This implements a UEFI Shell application that updates the EFI NOR
standalone UEFI Shell application
partition with the contents of STYX_EFI.Fv. Note that this means that a) EFI variables are preserved, and b) this updater can only be used on systems that have already been flashed with a firmware build based on this open source branch (and not on systems still running AMI firmware)
In order for the flasher to have access to the various PCDs that describe where STYX_EFI.Fv lives in the NOR, it needs to be built as part of the platform, but after STYX_EFI.Fv has been generated, which results in a chicken-and-egg situation. Therefore, the recommended way of generating the flasher is
- delete the Build/<platform> directory entirely
- build the platform
- build the platform again, but with -D DO_FLASHER=TRUE appended
Build with -m .../StyxFlashUefi.inf instead of rebuilding the whole platform?
Yes, that should be sufficient. I will add that.
The flasher application is called 'StyxFlashUefi'
Only style comments below, but one silly question before that: Is there some particular reason why the application embeds the FV instead of reading it from a filesystem? Or just that you figured it's small enough that it doesn't matter?
Two reasons: - simplicity; the actual code is *very* simply due to the fact that it can refer to the payload directly, and I am not a seasoned shell application hacker that has a clue how one would go about implementing it using file I/O etc - a generic flasher needs metadata that describes where the payload needs to go, and the .Fv file does not contain that, so it would involve a file format or a command line option with all the associated failure modes.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org
Platforms/AMD/Styx/Applications/StyxFlashUefi/Scripts/GccBase.lds | 86 ++++++++++++++++++ Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashImage.S | 25 +++++ Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.c | 96 ++++++++++++++++++++ Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf | 53 +++++++++++ Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc | 12 ++- Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc | 8 ++ Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc | 8 ++ 7 files changed, 286 insertions(+), 2 deletions(-)
diff --git a/Platforms/AMD/Styx/Applications/StyxFlashUefi/Scripts/GccBase.lds b/Platforms/AMD/Styx/Applications/StyxFlashUefi/Scripts/GccBase.lds new file mode 100644 index 000000000000..7a0c87c6e32b --- /dev/null +++ b/Platforms/AMD/Styx/Applications/StyxFlashUefi/Scripts/GccBase.lds @@ -0,0 +1,86 @@ +/** @file
- Unified linker script for GCC based builds
- Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
- Copyright (c) 2015 - 2017, Linaro Ltd. All rights reserved.<BR>
- (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
- This program and the accompanying materials are licensed and made available under
- the terms and conditions of the BSD License that accompanies this distribution.
- The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php.
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+SECTIONS {
- /*
- The PE/COFF binary consists of DOS and PE/COFF headers, and a sequence of
- section headers adding up to PECOFF_HEADER_SIZE bytes (which differs
- between 32-bit and 64-bit builds). The actual start of the .text section
- will be rounded up based on its actual alignment.
- */
- . = PECOFF_HEADER_SIZE;
- .text : ALIGN(CONSTANT(COMMONPAGESIZE)) {
- *(.text .text.* .stub .gnu.linkonce.t.*)
- *(.rodata .rodata.* .gnu.linkonce.r.*)
- *(.got .got.*)
- /*
* The contents of AutoGen.c files are mostly constant from the POV of the
* program, but most of it ends up in .data or .bss by default since few of
* the variable definitions that get emitted are declared as CONST.
* Unfortunately, we cannot pull it into the .text section entirely, since
* patchable PCDs are also emitted here, but we can at least move all of the
* emitted GUIDs here.
*/
- *:AutoGen.obj(.data.g*Guid)
- }
- /*
- The alignment of the .data section should be less than or equal to the
- alignment of the .text section. This ensures that the relative offset
- between these sections is the same in the ELF and the PE/COFF versions of
- this binary.
- */
- .data ALIGN(ALIGNOF(.text)) : ALIGN(CONSTANT(COMMONPAGESIZE)) {
- *(.data .data.* .gnu.linkonce.d.*)
- *(.bss .bss.*)
- *(.payload)
- }
- .eh_frame ALIGN(CONSTANT(COMMONPAGESIZE)) : {
- KEEP (*(.eh_frame))
- }
- .rela (INFO) : {
- *(.rela .rela.*)
- }
- .hii : ALIGN(CONSTANT(COMMONPAGESIZE)) {
- KEEP (*(.hii))
- }
- /*
- Retain the GNU build id but in a non-allocatable section so GenFw
- does not copy it into the PE/COFF image.
- */
- .build-id (INFO) : { *(.note.gnu.build-id) }
- /DISCARD/ : {
- *(.note.GNU-stack)
- *(.gnu_debuglink)
- *(.interp)
- *(.dynsym)
- *(.dynstr)
- *(.dynamic)
- *(.hash .gnu.hash)
- *(.comment)
- *(COMMON)
- }
+} diff --git a/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashImage.S b/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashImage.S new file mode 100644 index 000000000000..041339ee9b47 --- /dev/null +++ b/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashImage.S @@ -0,0 +1,25 @@ +/** @file
- Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR>
- This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD License
- which accompanies this distribution. The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
- .section ".payload"
- .align 12
+ASM_GLOBAL ASM_PFX(StyxFlashImageStart) +ASM_PFX(StyxFlashImageStart):
- .incbin "STYX_EFI.Fv"
- .align 2
+ASM_GLOBAL ASM_PFX(StyxFlashImageSize) +ASM_PFX(StyxFlashImageSize):
- .long . - ASM_PFX(StyxFlashImageStart)
diff --git a/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.c b/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.c new file mode 100644 index 000000000000..a7bdbffab891 --- /dev/null +++ b/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.c @@ -0,0 +1,96 @@ +/** @file
- Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR>
- This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD License
- which accompanies this distribution. The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <Uefi.h> +#include <Library/BaseMemoryLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiLib.h> +#include <Library/ShellCEntryLib.h>
Inconsistent whitespace. Not sorted.
Will fix
+#include <Protocol/AmdIscpDxeProtocol.h>
+#define UEFI_IMAGE_OFFSET FixedPcdGet64 (PcdFvBaseAddress) - FixedPcdGet64 (PcdFdBaseAddress) +#define BLOCK_SIZE SIZE_64KB
+STATIC AMD_ISCP_DXE_PROTOCOL *mIscpDxeProtocol; +STATIC UINT8 Buffer[BLOCK_SIZE];
+extern CONST UINT8 StyxFlashImageStart[]; +extern CONST UINT32 StyxFlashImageSize;
+/***
- Main entrypoint
- Establishes the main structure of the application.
- @retval 0 The application exited normally.
- @retval Other An error occurred.
+***/ +INTN +EFIAPI +ShellAppMain (
- IN UINTN Argc,
- IN CHAR16 **Argv
- )
+{
- EFI_STATUS Status;
- UINTN Index;
- INTN Remaining;
- Print(L"StyxFlashUefi: firmware updater for AMD Seattle based boards.\n");
Space after "Print". (Actually, this seems consistent on all Print statement in this function, and nothing else.)
Not sure how that happened :-) Will fix.
- Status = gBS->LocateProtocol (&gAmdIscpDxeProtocolGuid, NULL,
(VOID **)&mIscpDxeProtocol);
- if (EFI_ERROR (Status)) {
- Print(L"Failed to locate ISCP communication protocol, terminating...\n");
- return (INTN)Status;
- }
- Index = 0;
- Remaining = StyxFlashImageSize;
- do {
- Status = mIscpDxeProtocol->AmdExecuteEraseFvBlockDxe (
mIscpDxeProtocol,
UEFI_IMAGE_OFFSET + Index * BLOCK_SIZE,
BLOCK_SIZE);
- if (EFI_ERROR (Status)) {
Print(L"Erase failed!\n");
return (INTN)Status;
- }
- CopyMem (Buffer, StyxFlashImageStart + Index * BLOCK_SIZE,
MIN (Remaining, BLOCK_SIZE));
- Status = mIscpDxeProtocol->AmdExecuteUpdateFvBlockDxe (
mIscpDxeProtocol,
UEFI_IMAGE_OFFSET + Index * BLOCK_SIZE,
Buffer,
MIN (Remaining, BLOCK_SIZE));
- if (EFI_ERROR (Status)) {
Print(L"Update failed!\n");
return (INTN)Status;
- }
- Remaining -= BLOCK_SIZE;
- Index++;
- Print(L"Block %d of %d updated\n", Index, StyxFlashImageSize / BLOCK_SIZE);
- } while (Remaining > 0);
- Print(L"\nDone!\n");
- return 0;
+} diff --git a/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf b/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf new file mode 100644 index 000000000000..2ad7c1b98ef1 --- /dev/null +++ b/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf @@ -0,0 +1,53 @@ +#/** @file +# +# Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR> +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#**/
+[Defines]
- INF_VERSION = 0x00010006
Not 1.25?
Copy/paste from HelloWorld or some other example app I used. Will fix.
- BASE_NAME = StyxFlashUefi
- FILE_GUID = 07b65d9d-b1a2-416e-bd04-0b61b775f924
- MODULE_TYPE = UEFI_APPLICATION
- VERSION_STRING = 0.1
- ENTRY_POINT = ShellCEntryLib
+# +# VALID_ARCHITECTURES = AARCH64 +#
+[Sources]
- StyxFlashImage.S
- StyxFlashUefi.c
+[Packages]
- AmdModulePkg/AmdModulePkg.dec
- ArmPkg/ArmPkg.dec
- MdePkg/MdePkg.dec
- ShellPkg/ShellPkg.dec
+[LibraryClasses]
- BaseMemoryLib
- UefiBootServicesTableLib
- UefiLib
- ShellCEntryLib
+[Protocols]
- gAmdIscpDxeProtocolGuid
+[FixedPcd]
- gArmTokenSpaceGuid.PcdFdBaseAddress
- gArmTokenSpaceGuid.PcdFvBaseAddress
+[BuildOptions]
- *_*_*_CC_FLAGS = -mcmodel=small
- *_*_*_DLINK_FLAGS = -z common-page-size=0x1000 -Wl,-T,$(MODULE_DIR)/Scripts/GccBase.lds
- *_*_*_PLATFORM_FLAGS = -I$(BIN_DIR)/../FV
Ah, _that's_ how you find STYX_EFI.Fv? :)
Yes. Keepin' it simple ...
diff --git a/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc b/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc index 091914c047a3..90cda24ae49d 100644 --- a/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc +++ b/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc @@ -17,8 +17,9 @@ ################################################################################ [Defines]
-DEFINE NUM_CORES = 4 -DEFINE DO_KCS = 0 +DEFINE NUM_CORES = 4 +DEFINE DO_KCS = 0 +DEFINE DO_FLASHER = FALSE
PLATFORM_NAME = Cello PLATFORM_GUID = 77861b3e-74b0-4ff3-8d18-c5ba5803e1bf @@ -690,3 +691,10 @@ DEFINE DO_KCS = 0 !ifdef $(RENESAS_XHCI_FW_DIR) OpenPlatformPkg/Drivers/Xhci/RenesasFirmwarePD720202/RenesasFirmwarePD720202.inf !endif
+!if $(DO_FLASHER) == TRUE
- OpenPlatformPkg/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf {
<LibraryClasses>
ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf
- }
+!endif diff --git a/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc b/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc index 57d1425b2c8f..5b7d7f4a7b4a 100644 --- a/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc +++ b/Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc @@ -21,6 +21,7 @@ DEFINE NUM_CORES = 4 DEFINE DO_PSCI = 1 DEFINE DO_ISCP = 1 DEFINE DO_KCS = 1 +DEFINE DO_FLASHER = FALSE
PLATFORM_NAME = Overdrive1000 PLATFORM_GUID = 36774DD7-20DE-4C5B-8722-f8861DFF1F16 @@ -701,3 +702,10 @@ DEFINE DO_KCS = 1 gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000 }
+!if $(DO_FLASHER) == TRUE
- OpenPlatformPkg/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf {
<LibraryClasses>
ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf
- }
+!endif diff --git a/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc b/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc index 6c284fb3b7db..662a15a9ccea 100644 --- a/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc +++ b/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc @@ -22,6 +22,7 @@ DEFINE NUM_CORES = 8 DEFINE DO_PSCI = 1 DEFINE DO_ISCP = 1 DEFINE DO_KCS = 1 +DEFINE DO_FLASHER = FALSE
PLATFORM_NAME = Overdrive PLATFORM_GUID = B2296C02-9DA1-4CD1-BD48-4D4F0F1276EB @@ -752,3 +753,10 @@ DEFINE DO_KCS = 1 gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000 }
+!if $(DO_FLASHER) == TRUE
- OpenPlatformPkg/Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf {
<LibraryClasses>
ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf
- }
+!endif
2.9.3
On Tue, Jun 27, 2017 at 04:39:47PM +0000, Ard Biesheuvel wrote:
On 27 June 2017 at 16:33, Leif Lindholm leif.lindholm@linaro.org wrote:
On Tue, Jun 27, 2017 at 01:21:45PM +0000, Ard Biesheuvel wrote:
This implements a UEFI Shell application that updates the EFI NOR
standalone UEFI Shell application
partition with the contents of STYX_EFI.Fv. Note that this means that a) EFI variables are preserved, and b) this updater can only be used on systems that have already been flashed with a firmware build based on this open source branch (and not on systems still running AMI firmware)
Request for clarification based on your explanation below: Presumably b) is for one or both of these reasons: 1) AMI firmware will not produce all protocols needed for this application to run (just like this firmware will not produce all protocols the AMI updater needs)? 2) This application does not zero out the variable area?
In order for the flasher to have access to the various PCDs that describe where STYX_EFI.Fv lives in the NOR, it needs to be built as part of the platform, but after STYX_EFI.Fv has been generated, which results in a chicken-and-egg situation. Therefore, the recommended way of generating the flasher is
- delete the Build/<platform> directory entirely
- build the platform
- build the platform again, but with -D DO_FLASHER=TRUE appended
Build with -m .../StyxFlashUefi.inf instead of rebuilding the whole platform?
Yes, that should be sufficient. I will add that.
The flasher application is called 'StyxFlashUefi'
Only style comments below, but one silly question before that: Is there some particular reason why the application embeds the FV instead of reading it from a filesystem? Or just that you figured it's small enough that it doesn't matter?
Two reasons:
- simplicity; the actual code is *very* simply due to the fact that it
can refer to the payload directly, and I am not a seasoned shell application hacker that has a clue how one would go about implementing it using file I/O etc
- a generic flasher needs metadata that describes where the payload
needs to go, and the .Fv file does not contain that, so it would involve a file format or a command line option with all the associated failure modes.
Right, so basically because PcdFvBaseAddress and PcdFdBaseAddress could change? But would such a change not mean that variables would not be preserved after all?
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org
Platforms/AMD/Styx/Applications/StyxFlashUefi/Scripts/GccBase.lds | 86 ++++++++++++++++++ Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashImage.S | 25 +++++ Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.c | 96 ++++++++++++++++++++ Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf | 53 +++++++++++ Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc | 12 ++- Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc | 8 ++ Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc | 8 ++ 7 files changed, 286 insertions(+), 2 deletions(-)
On 27 June 2017 at 17:00, Leif Lindholm leif.lindholm@linaro.org wrote:
On Tue, Jun 27, 2017 at 04:39:47PM +0000, Ard Biesheuvel wrote:
On 27 June 2017 at 16:33, Leif Lindholm leif.lindholm@linaro.org wrote:
On Tue, Jun 27, 2017 at 01:21:45PM +0000, Ard Biesheuvel wrote:
This implements a UEFI Shell application that updates the EFI NOR
standalone UEFI Shell application
partition with the contents of STYX_EFI.Fv. Note that this means that a) EFI variables are preserved, and b) this updater can only be used on systems that have already been flashed with a firmware build based on this open source branch (and not on systems still running AMI firmware)
Request for clarification based on your explanation below: Presumably b) is for one or both of these reasons:
- AMI firmware will not produce all protocols needed for this application to run (just like this firmware will not produce all protocols the AMI updater needs)?
- This application does not zero out the variable area?
The AMI firmware is also based on SeattleFDK, so it does produce the ISCP protocol that exposes the NOR read/write/erase methods. This is what makes it dangerous, given that the flasher will most likely run happily, but will not leave the NOR in a state where a varstore FV header appears in the expected place. This is what will make the firmware crash.
Note that none of these issues are particularly difficult to deal with, but it increases the complexity of this tools, which is not intended as a production quality firmware update distribution method but simply to allow me to distribute firmware updates to people like Lorenzo and Marc, and now some Cello users as well which shouldn't have been shipped boards to begin with.
In order for the flasher to have access to the various PCDs that describe where STYX_EFI.Fv lives in the NOR, it needs to be built as part of the platform, but after STYX_EFI.Fv has been generated, which results in a chicken-and-egg situation. Therefore, the recommended way of generating the flasher is
- delete the Build/<platform> directory entirely
- build the platform
- build the platform again, but with -D DO_FLASHER=TRUE appended
Build with -m .../StyxFlashUefi.inf instead of rebuilding the whole platform?
Yes, that should be sufficient. I will add that.
The flasher application is called 'StyxFlashUefi'
Only style comments below, but one silly question before that: Is there some particular reason why the application embeds the FV instead of reading it from a filesystem? Or just that you figured it's small enough that it doesn't matter?
Two reasons:
- simplicity; the actual code is *very* simply due to the fact that it
can refer to the payload directly, and I am not a seasoned shell application hacker that has a clue how one would go about implementing it using file I/O etc
- a generic flasher needs metadata that describes where the payload
needs to go, and the .Fv file does not contain that, so it would involve a file format or a command line option with all the associated failure modes.
Right, so basically because PcdFvBaseAddress and PcdFdBaseAddress could change? But would such a change not mean that variables would not be preserved after all?
Not just because they could change, but because their value is set in the .FDF, and so any attempt to obtain the values elsewhere would involve adding a redundant definition, which I would like to avoid.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org
Platforms/AMD/Styx/Applications/StyxFlashUefi/Scripts/GccBase.lds | 86 ++++++++++++++++++ Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashImage.S | 25 +++++ Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.c | 96 ++++++++++++++++++++ Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf | 53 +++++++++++ Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc | 12 ++- Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc | 8 ++ Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc | 8 ++ 7 files changed, 286 insertions(+), 2 deletions(-)
On Tue, Jun 27, 2017 at 05:24:30PM +0000, Ard Biesheuvel wrote:
On 27 June 2017 at 17:00, Leif Lindholm leif.lindholm@linaro.org wrote:
On Tue, Jun 27, 2017 at 04:39:47PM +0000, Ard Biesheuvel wrote:
On 27 June 2017 at 16:33, Leif Lindholm leif.lindholm@linaro.org wrote:
On Tue, Jun 27, 2017 at 01:21:45PM +0000, Ard Biesheuvel wrote:
This implements a UEFI Shell application that updates the EFI NOR
standalone UEFI Shell application
partition with the contents of STYX_EFI.Fv. Note that this means that a) EFI variables are preserved, and b) this updater can only be used on systems that have already been flashed with a firmware build based on this open source branch (and not on systems still running AMI firmware)
Request for clarification based on your explanation below: Presumably b) is for one or both of these reasons:
- AMI firmware will not produce all protocols needed for this application to run (just like this firmware will not produce all protocols the AMI updater needs)?
- This application does not zero out the variable area?
The AMI firmware is also based on SeattleFDK, so it does produce the ISCP protocol that exposes the NOR read/write/erase methods. This is what makes it dangerous, given that the flasher will most likely run happily, but will not leave the NOR in a state where a varstore FV header appears in the expected place. This is what will make the firmware crash.
Note that none of these issues are particularly difficult to deal with, but it increases the complexity of this tools, which is not intended as a production quality firmware update distribution method but simply to allow me to distribute firmware updates to people like Lorenzo and Marc, and now some Cello users as well which shouldn't have been shipped boards to begin with.
All I'm really getting at with these questions around a very much welcome new tool is that I have a feeling it isn't necessarily end-user proof at this stage, so I think I would like to see either a few warnings in this commit message (which currently reads more like it's saying more along the lines of "it will only work if" than "you will become a customer of Dediprog if you try") or some attempt to determine whether we are on a platform where it is safe to attempt an upgrade.
In order for the flasher to have access to the various PCDs that describe where STYX_EFI.Fv lives in the NOR, it needs to be built as part of the platform, but after STYX_EFI.Fv has been generated, which results in a chicken-and-egg situation. Therefore, the recommended way of generating the flasher is
- delete the Build/<platform> directory entirely
- build the platform
- build the platform again, but with -D DO_FLASHER=TRUE appended
Build with -m .../StyxFlashUefi.inf instead of rebuilding the whole platform?
Yes, that should be sufficient. I will add that.
The flasher application is called 'StyxFlashUefi'
Only style comments below, but one silly question before that: Is there some particular reason why the application embeds the FV instead of reading it from a filesystem? Or just that you figured it's small enough that it doesn't matter?
Two reasons:
- simplicity; the actual code is *very* simply due to the fact that it
can refer to the payload directly, and I am not a seasoned shell application hacker that has a clue how one would go about implementing it using file I/O etc
- a generic flasher needs metadata that describes where the payload
needs to go, and the .Fv file does not contain that, so it would involve a file format or a command line option with all the associated failure modes.
Right, so basically because PcdFvBaseAddress and PcdFdBaseAddress could change? But would such a change not mean that variables would not be preserved after all?
Not just because they could change, but because their value is set in the .FDF, and so any attempt to obtain the values elsewhere would involve adding a redundant definition, which I would like to avoid.
Oh, indeed.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org
Platforms/AMD/Styx/Applications/StyxFlashUefi/Scripts/GccBase.lds | 86 ++++++++++++++++++ Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashImage.S | 25 +++++ Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.c | 96 ++++++++++++++++++++ Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf | 53 +++++++++++ Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc | 12 ++- Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc | 8 ++ Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc | 8 ++ 7 files changed, 286 insertions(+), 2 deletions(-)
On 27 June 2017 at 17:48, Leif Lindholm leif.lindholm@linaro.org wrote:
On Tue, Jun 27, 2017 at 05:24:30PM +0000, Ard Biesheuvel wrote:
On 27 June 2017 at 17:00, Leif Lindholm leif.lindholm@linaro.org wrote:
On Tue, Jun 27, 2017 at 04:39:47PM +0000, Ard Biesheuvel wrote:
On 27 June 2017 at 16:33, Leif Lindholm leif.lindholm@linaro.org wrote:
On Tue, Jun 27, 2017 at 01:21:45PM +0000, Ard Biesheuvel wrote:
This implements a UEFI Shell application that updates the EFI NOR
standalone UEFI Shell application
partition with the contents of STYX_EFI.Fv. Note that this means that a) EFI variables are preserved, and b) this updater can only be used on systems that have already been flashed with a firmware build based on this open source branch (and not on systems still running AMI firmware)
Request for clarification based on your explanation below: Presumably b) is for one or both of these reasons:
- AMI firmware will not produce all protocols needed for this application to run (just like this firmware will not produce all protocols the AMI updater needs)?
- This application does not zero out the variable area?
The AMI firmware is also based on SeattleFDK, so it does produce the ISCP protocol that exposes the NOR read/write/erase methods. This is what makes it dangerous, given that the flasher will most likely run happily, but will not leave the NOR in a state where a varstore FV header appears in the expected place. This is what will make the firmware crash.
Note that none of these issues are particularly difficult to deal with, but it increases the complexity of this tools, which is not intended as a production quality firmware update distribution method but simply to allow me to distribute firmware updates to people like Lorenzo and Marc, and now some Cello users as well which shouldn't have been shipped boards to begin with.
All I'm really getting at with these questions around a very much welcome new tool is that I have a feeling it isn't necessarily end-user proof at this stage, so I think I would like to see either a few warnings in this commit message (which currently reads more like it's saying more along the lines of "it will only work if" than "you will become a customer of Dediprog if you try") or some attempt to determine whether we are on a platform where it is safe to attempt an upgrade.
Oh, this is absolutely unsuitable for general use. For instance, it does not distinguish between Cello, Overdrive and Overdrive1000, nor does it perform any kind of verification after the flash, all of which are not that difficult to implement, but simply not things that I can be bothered to care about at the moment, given the sorry state of Cello, and the fact that the only three users of this firmware for Overdrive are one floor down from where your desk is.
So for now, it is either merging this code, with perhaps some discouraging capitalized scary words added to the commit message, or just disregarding the patch for now, in the hope that someone else (Alan perhaps?) can be bothered to pick it up later and polish it up a bit. I honestly don't care either way.
In order for the flasher to have access to the various PCDs that describe where STYX_EFI.Fv lives in the NOR, it needs to be built as part of the platform, but after STYX_EFI.Fv has been generated, which results in a chicken-and-egg situation. Therefore, the recommended way of generating the flasher is
- delete the Build/<platform> directory entirely
- build the platform
- build the platform again, but with -D DO_FLASHER=TRUE appended
Build with -m .../StyxFlashUefi.inf instead of rebuilding the whole platform?
Yes, that should be sufficient. I will add that.
The flasher application is called 'StyxFlashUefi'
Only style comments below, but one silly question before that: Is there some particular reason why the application embeds the FV instead of reading it from a filesystem? Or just that you figured it's small enough that it doesn't matter?
Two reasons:
- simplicity; the actual code is *very* simply due to the fact that it
can refer to the payload directly, and I am not a seasoned shell application hacker that has a clue how one would go about implementing it using file I/O etc
- a generic flasher needs metadata that describes where the payload
needs to go, and the .Fv file does not contain that, so it would involve a file format or a command line option with all the associated failure modes.
Right, so basically because PcdFvBaseAddress and PcdFdBaseAddress could change? But would such a change not mean that variables would not be preserved after all?
Not just because they could change, but because their value is set in the .FDF, and so any attempt to obtain the values elsewhere would involve adding a redundant definition, which I would like to avoid.
Oh, indeed.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org
Platforms/AMD/Styx/Applications/StyxFlashUefi/Scripts/GccBase.lds | 86 ++++++++++++++++++ Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashImage.S | 25 +++++ Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.c | 96 ++++++++++++++++++++ Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf | 53 +++++++++++ Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc | 12 ++- Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc | 8 ++ Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc | 8 ++ 7 files changed, 286 insertions(+), 2 deletions(-)
On Tue, Jun 27, 2017 at 10:56 AM, Ard Biesheuvel ard.biesheuvel@linaro.org wrote:
On 27 June 2017 at 17:48, Leif Lindholm leif.lindholm@linaro.org wrote:
On Tue, Jun 27, 2017 at 05:24:30PM +0000, Ard Biesheuvel wrote:
On 27 June 2017 at 17:00, Leif Lindholm leif.lindholm@linaro.org wrote:
On Tue, Jun 27, 2017 at 04:39:47PM +0000, Ard Biesheuvel wrote:
On 27 June 2017 at 16:33, Leif Lindholm leif.lindholm@linaro.org wrote:
On Tue, Jun 27, 2017 at 01:21:45PM +0000, Ard Biesheuvel wrote: > This implements a UEFI Shell application that updates the EFI NOR
standalone UEFI Shell application
> partition with the contents of STYX_EFI.Fv. Note that this means that > a) EFI variables are preserved, and > b) this updater can only be used on systems that have already been flashed > with a firmware build based on this open source branch (and not on systems > still running AMI firmware)
Request for clarification based on your explanation below: Presumably b) is for one or both of these reasons:
- AMI firmware will not produce all protocols needed for this application to run (just like this firmware will not produce all protocols the AMI updater needs)?
- This application does not zero out the variable area?
The AMI firmware is also based on SeattleFDK, so it does produce the ISCP protocol that exposes the NOR read/write/erase methods. This is what makes it dangerous, given that the flasher will most likely run happily, but will not leave the NOR in a state where a varstore FV header appears in the expected place. This is what will make the firmware crash.
Note that none of these issues are particularly difficult to deal with, but it increases the complexity of this tools, which is not intended as a production quality firmware update distribution method but simply to allow me to distribute firmware updates to people like Lorenzo and Marc, and now some Cello users as well which shouldn't have been shipped boards to begin with.
All I'm really getting at with these questions around a very much welcome new tool is that I have a feeling it isn't necessarily end-user proof at this stage, so I think I would like to see either a few warnings in this commit message (which currently reads more like it's saying more along the lines of "it will only work if" than "you will become a customer of Dediprog if you try") or some attempt to determine whether we are on a platform where it is safe to attempt an upgrade.
Oh, this is absolutely unsuitable for general use. For instance, it does not distinguish between Cello, Overdrive and Overdrive1000, nor does it perform any kind of verification after the flash, all of which are not that difficult to implement, but simply not things that I can be bothered to care about at the moment, given the sorry state of Cello, and the fact that the only three users of this firmware for Overdrive are one floor down from where your desk is.
So for now, it is either merging this code, with perhaps some discouraging capitalized scary words added to the commit message, or just disregarding the patch for now, in the hope that someone else (Alan perhaps?) can be bothered to pick it up later and polish it up a bit. I honestly don't care either way.
I'll give this a try. I can use a Bus Pirate to program the flash, but it's slow and I don't have a proper cable, so I have to connect the wires individually. I'd think merging with warnings would be useful. It won't be built by default, so users would have to deliberately use this.
Roy
> In order for the flasher to have access to the various PCDs that describe > where STYX_EFI.Fv lives in the NOR, it needs to be built as part of the > platform, but after STYX_EFI.Fv has been generated, which results in a > chicken-and-egg situation. Therefore, the recommended way of generating > the flasher is > > 1) delete the Build/<platform> directory entirely > 2) build the platform > 3) build the platform again, but with -D DO_FLASHER=TRUE appended
Build with -m .../StyxFlashUefi.inf instead of rebuilding the whole platform?
Yes, that should be sufficient. I will add that.
> The flasher application is called 'StyxFlashUefi'
Only style comments below, but one silly question before that: Is there some particular reason why the application embeds the FV instead of reading it from a filesystem? Or just that you figured it's small enough that it doesn't matter?
Two reasons:
- simplicity; the actual code is *very* simply due to the fact that it
can refer to the payload directly, and I am not a seasoned shell application hacker that has a clue how one would go about implementing it using file I/O etc
- a generic flasher needs metadata that describes where the payload
needs to go, and the .Fv file does not contain that, so it would involve a file format or a command line option with all the associated failure modes.
Right, so basically because PcdFvBaseAddress and PcdFdBaseAddress could change? But would such a change not mean that variables would not be preserved after all?
Not just because they could change, but because their value is set in the .FDF, and so any attempt to obtain the values elsewhere would involve adding a redundant definition, which I would like to avoid.
Oh, indeed.
> Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Ard Biesheuvel ard.biesheuvel@linaro.org > --- > Platforms/AMD/Styx/Applications/StyxFlashUefi/Scripts/GccBase.lds | 86 ++++++++++++++++++ > Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashImage.S | 25 +++++ > Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.c | 96 ++++++++++++++++++++ > Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf | 53 +++++++++++ > Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc | 12 ++- > Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc | 8 ++ > Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc | 8 ++ > 7 files changed, 286 insertions(+), 2 deletions(-)
On Tue, Jun 27, 2017 at 05:56:35PM +0000, Ard Biesheuvel wrote:
On 27 June 2017 at 17:48, Leif Lindholm leif.lindholm@linaro.org wrote:
On Tue, Jun 27, 2017 at 05:24:30PM +0000, Ard Biesheuvel wrote:
On 27 June 2017 at 17:00, Leif Lindholm leif.lindholm@linaro.org wrote:
On Tue, Jun 27, 2017 at 04:39:47PM +0000, Ard Biesheuvel wrote:
On 27 June 2017 at 16:33, Leif Lindholm leif.lindholm@linaro.org wrote:
On Tue, Jun 27, 2017 at 01:21:45PM +0000, Ard Biesheuvel wrote: > This implements a UEFI Shell application that updates the EFI NOR
standalone UEFI Shell application
> partition with the contents of STYX_EFI.Fv. Note that this means that > a) EFI variables are preserved, and > b) this updater can only be used on systems that have already been flashed > with a firmware build based on this open source branch (and not on systems > still running AMI firmware)
Request for clarification based on your explanation below: Presumably b) is for one or both of these reasons:
- AMI firmware will not produce all protocols needed for this application to run (just like this firmware will not produce all protocols the AMI updater needs)?
- This application does not zero out the variable area?
The AMI firmware is also based on SeattleFDK, so it does produce the ISCP protocol that exposes the NOR read/write/erase methods. This is what makes it dangerous, given that the flasher will most likely run happily, but will not leave the NOR in a state where a varstore FV header appears in the expected place. This is what will make the firmware crash.
Note that none of these issues are particularly difficult to deal with, but it increases the complexity of this tools, which is not intended as a production quality firmware update distribution method but simply to allow me to distribute firmware updates to people like Lorenzo and Marc, and now some Cello users as well which shouldn't have been shipped boards to begin with.
All I'm really getting at with these questions around a very much welcome new tool is that I have a feeling it isn't necessarily end-user proof at this stage, so I think I would like to see either a few warnings in this commit message (which currently reads more like it's saying more along the lines of "it will only work if" than "you will become a customer of Dediprog if you try") or some attempt to determine whether we are on a platform where it is safe to attempt an upgrade.
Oh, this is absolutely unsuitable for general use. For instance, it does not distinguish between Cello, Overdrive and Overdrive1000, nor does it perform any kind of verification after the flash, all of which are not that difficult to implement, but simply not things that I can be bothered to care about at the moment, given the sorry state of Cello, and the fact that the only three users of this firmware for Overdrive are one floor down from where your desk is.
Yeah, I get it.
So for now, it is either merging this code, with perhaps some discouraging capitalized scary words added to the commit message, or just disregarding the patch for now, in the hope that someone else (Alan perhaps?) can be bothered to pick it up later and polish it up a bit. I honestly don't care either way.
I'm good with some capitalized scary words.
/ Leif
On Tue, Jun 27, 2017 at 11:53 AM, Leif Lindholm leif.lindholm@linaro.org wrote:
On Tue, Jun 27, 2017 at 05:56:35PM +0000, Ard Biesheuvel wrote:
On 27 June 2017 at 17:48, Leif Lindholm leif.lindholm@linaro.org wrote:
On Tue, Jun 27, 2017 at 05:24:30PM +0000, Ard Biesheuvel wrote:
On 27 June 2017 at 17:00, Leif Lindholm leif.lindholm@linaro.org wrote:
On Tue, Jun 27, 2017 at 04:39:47PM +0000, Ard Biesheuvel wrote:
On 27 June 2017 at 16:33, Leif Lindholm leif.lindholm@linaro.org wrote: > On Tue, Jun 27, 2017 at 01:21:45PM +0000, Ard Biesheuvel wrote: >> This implements a UEFI Shell application that updates the EFI NOR > > standalone UEFI Shell application > >> partition with the contents of STYX_EFI.Fv. Note that this means that >> a) EFI variables are preserved, and >> b) this updater can only be used on systems that have already been flashed >> with a firmware build based on this open source branch (and not on systems >> still running AMI firmware)
Request for clarification based on your explanation below: Presumably b) is for one or both of these reasons:
- AMI firmware will not produce all protocols needed for this application to run (just like this firmware will not produce all protocols the AMI updater needs)?
- This application does not zero out the variable area?
The AMI firmware is also based on SeattleFDK, so it does produce the ISCP protocol that exposes the NOR read/write/erase methods. This is what makes it dangerous, given that the flasher will most likely run happily, but will not leave the NOR in a state where a varstore FV header appears in the expected place. This is what will make the firmware crash.
Note that none of these issues are particularly difficult to deal with, but it increases the complexity of this tools, which is not intended as a production quality firmware update distribution method but simply to allow me to distribute firmware updates to people like Lorenzo and Marc, and now some Cello users as well which shouldn't have been shipped boards to begin with.
All I'm really getting at with these questions around a very much welcome new tool is that I have a feeling it isn't necessarily end-user proof at this stage, so I think I would like to see either a few warnings in this commit message (which currently reads more like it's saying more along the lines of "it will only work if" than "you will become a customer of Dediprog if you try") or some attempt to determine whether we are on a platform where it is safe to attempt an upgrade.
Oh, this is absolutely unsuitable for general use. For instance, it does not distinguish between Cello, Overdrive and Overdrive1000, nor does it perform any kind of verification after the flash, all of which are not that difficult to implement, but simply not things that I can be bothered to care about at the moment, given the sorry state of Cello, and the fact that the only three users of this firmware for Overdrive are one floor down from where your desk is.
Yeah, I get it.
So for now, it is either merging this code, with perhaps some discouraging capitalized scary words added to the commit message, or just disregarding the patch for now, in the hope that someone else (Alan perhaps?) can be bothered to pick it up later and polish it up a bit. I honestly don't care either way.
I'm good with some capitalized scary words.
/ Leif
You can add: Tested-by: Roy Franz roy.franz@cavium.com
I did see some unexpected output in the early Linux boot, but that is unrelated to this patch, as I didn't apply other patches from this series, as some of them were already on the master branch. I built against edk2 51bf49ee53a289 (Current UDK2017 branch) and OpenPlatformPkg 8a854db1f5, and I'm seeing the following:
EFI stub: Booting Linux Kernel... EFI stub: Using DTB from configuration table EFI stub: Exiting boot services and installing virtual address map... [ 0.403578] ssp-pl022 e1020000.ssp: probe: no chip select defined [ 0.409716] ssp-pl022 e1030000.ssp: Failed to work in dma mode, work without!
The boot continues, and seems to work fine, however the two ssp-pl022 messages are not there on the firmware build that I got from Ard with the SATA detection timeout fix.
Roy
On 27 June 2017 at 21:29, Roy Franz rfranz@cavium.com wrote:
On Tue, Jun 27, 2017 at 11:53 AM, Leif Lindholm leif.lindholm@linaro.org wrote:
On Tue, Jun 27, 2017 at 05:56:35PM +0000, Ard Biesheuvel wrote:
On 27 June 2017 at 17:48, Leif Lindholm leif.lindholm@linaro.org wrote:
On Tue, Jun 27, 2017 at 05:24:30PM +0000, Ard Biesheuvel wrote:
On 27 June 2017 at 17:00, Leif Lindholm leif.lindholm@linaro.org wrote:
On Tue, Jun 27, 2017 at 04:39:47PM +0000, Ard Biesheuvel wrote: > On 27 June 2017 at 16:33, Leif Lindholm leif.lindholm@linaro.org wrote: > > On Tue, Jun 27, 2017 at 01:21:45PM +0000, Ard Biesheuvel wrote: > >> This implements a UEFI Shell application that updates the EFI NOR > > > > standalone UEFI Shell application > > > >> partition with the contents of STYX_EFI.Fv. Note that this means that > >> a) EFI variables are preserved, and > >> b) this updater can only be used on systems that have already been flashed > >> with a firmware build based on this open source branch (and not on systems > >> still running AMI firmware)
Request for clarification based on your explanation below: Presumably b) is for one or both of these reasons:
- AMI firmware will not produce all protocols needed for this application to run (just like this firmware will not produce all protocols the AMI updater needs)?
- This application does not zero out the variable area?
The AMI firmware is also based on SeattleFDK, so it does produce the ISCP protocol that exposes the NOR read/write/erase methods. This is what makes it dangerous, given that the flasher will most likely run happily, but will not leave the NOR in a state where a varstore FV header appears in the expected place. This is what will make the firmware crash.
Note that none of these issues are particularly difficult to deal with, but it increases the complexity of this tools, which is not intended as a production quality firmware update distribution method but simply to allow me to distribute firmware updates to people like Lorenzo and Marc, and now some Cello users as well which shouldn't have been shipped boards to begin with.
All I'm really getting at with these questions around a very much welcome new tool is that I have a feeling it isn't necessarily end-user proof at this stage, so I think I would like to see either a few warnings in this commit message (which currently reads more like it's saying more along the lines of "it will only work if" than "you will become a customer of Dediprog if you try") or some attempt to determine whether we are on a platform where it is safe to attempt an upgrade.
Oh, this is absolutely unsuitable for general use. For instance, it does not distinguish between Cello, Overdrive and Overdrive1000, nor does it perform any kind of verification after the flash, all of which are not that difficult to implement, but simply not things that I can be bothered to care about at the moment, given the sorry state of Cello, and the fact that the only three users of this firmware for Overdrive are one floor down from where your desk is.
Yeah, I get it.
So for now, it is either merging this code, with perhaps some discouraging capitalized scary words added to the commit message, or just disregarding the patch for now, in the hope that someone else (Alan perhaps?) can be bothered to pick it up later and polish it up a bit. I honestly don't care either way.
I'm good with some capitalized scary words.
/ Leif
You can add: Tested-by: Roy Franz roy.franz@cavium.com
Thanks!
I did see some unexpected output in the early Linux boot, but that is unrelated to this patch, as I didn't apply other patches from this series, as some of them were already on the master branch. I built against edk2 51bf49ee53a289 (Current UDK2017 branch) and OpenPlatformPkg 8a854db1f5, and I'm seeing the following:
EFI stub: Booting Linux Kernel... EFI stub: Using DTB from configuration table EFI stub: Exiting boot services and installing virtual address map... [ 0.403578] ssp-pl022 e1020000.ssp: probe: no chip select defined [ 0.409716] ssp-pl022 e1030000.ssp: Failed to work in dma mode, work without!
The boot continues, and seems to work fine, however the two ssp-pl022 messages are not there on the firmware build that I got from Ard with the SATA detection timeout fix.
This is because you are now booting in DT mode. The messages themselves are harmless afaict.
You can switch back to ACPI in the UEFI setup menu (under Device Manager) and it will stick
On Tue, Jun 27, 2017 at 01:21:35PM +0000, Ard Biesheuvel wrote:
A couple of fixes I applied to get Cello in a slightly better shape (although the observed SATA timeout issue requires a change in the core code)
v2:
- added patch to disable second SATA controller on Overdrive
- use correct port mode mask for overdrive (#3)
- update binary AmdModulePkg modules to latest version
- add UEFI shell app to reflash to EFI code partition in the NOR
- add SMMU enable switch to Cello and Overdrive 1000
For 1-2,7-8 Reviewed-by: Leif Lindholm leif.lindholm@linaro.org
Ard Biesheuvel (10): Platforms/AMD/Styx: remove incorrect timer frequency Platforms/AMD/Overdrive: disable second SATA port Platforms/AMD/Styx: set SATA port mode to Gen3 on all ports Platforms/AMD/StyxDtbLoaderLib: disable SMMUs for absent hardware Platform/AMD/Styx: add SMMU override to Cello and Overdrive1000 Platforms/AMD/Cello: add device tree support Platforms/AMD/Cello: reduce core count to 4 Platforms/AMD/Cello: set firmware vendor field to 'LeMaker Cello' Platforms/AMD/Styx/Binary: update binary modules to latest version Platforms/AMD/Styx: add command line flash tool
Platforms/AMD/Styx/Applications/StyxFlashUefi/Scripts/GccBase.lds | 86 ++++++++++++++++++ Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashImage.S | 25 +++++ Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.c | 96 ++++++++++++++++++++ Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf | 53 +++++++++++ Platforms/AMD/Styx/Binary/AmdModulePkg/Gionb/Gionb.efi | Bin 43296 -> 36768 bytes Platforms/AMD/Styx/Binary/AmdModulePkg/Gionb/Gionb.inf | 14 ++- Platforms/AMD/Styx/Binary/AmdModulePkg/Iscp/IscpDxe.efi | Bin 262144 -> 262144 bytes Platforms/AMD/Styx/Binary/AmdModulePkg/Iscp/IscpPei.efi | Bin 10336 -> 6976 bytes Platforms/AMD/Styx/Binary/AmdModulePkg/SnpDxe/SnpDxePort0.efi | Bin 30272 -> 24992 bytes Platforms/AMD/Styx/Binary/AmdModulePkg/SnpDxe/SnpDxePort1.efi | Bin 30272 -> 24992 bytes Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc | 39 ++++++-- Platforms/AMD/Styx/CelloBoard/CelloBoard.fdf | 9 ++ Platforms/AMD/Styx/Library/StyxDtbLoaderLib/StyxDtbLoaderLib.c | 9 +- Platforms/AMD/Styx/Overdrive1000Board/Overdrive1000Board.dsc | 19 ++-- Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc | 20 ++-- 15 files changed, 338 insertions(+), 32 deletions(-) create mode 100644 Platforms/AMD/Styx/Applications/StyxFlashUefi/Scripts/GccBase.lds create mode 100644 Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashImage.S create mode 100644 Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.c create mode 100644 Platforms/AMD/Styx/Applications/StyxFlashUefi/StyxFlashUefi.inf
-- 2.9.3