diff options
author | Ard Biesheuvel <ard.biesheuvel@arm.com> | 2020-05-05 14:39:21 +0200 |
---|---|---|
committer | Ard Biesheuvel <ard.biesheuvel@arm.com> | 2020-05-06 14:49:14 +0200 |
commit | 1301a831554fb49a2843a9a08a985e25cb260aab (patch) | |
tree | 443333dece90898c5109db8ae5490472bd25d607 /Platform/RaspberryPi/RPi3 | |
parent | cd653599c2d9d05140b7ace6b4d51a5c438999ee (diff) |
Platform/RaspberryPi: introduce DebugDualSerialPortLib
On DEBUG builds that use the serial port directly for debug output,
every module reinitializes the UART hardware, through the DebugLib
constructor calling SerialPortInitialize.
This is unnecessary, but usually harmless. However, in cases where this
requires information that is non-trivial to obtain (e.g., the rate of
the clock source feeding the baud clock), it results in a special kind
of dependency hell that can only be fully appreciated by seasoned EDK2
connoisseurs [0].
As a first step towards solving this mess, implement a special version
of the Raspberry Pi dual serial port library that only implements the
SerialPortInitialize() and SerialPortWrite() library functions, and make
the former an empty stub. This makes it only suitable for use by modules
that inherit a dependency on SerialPortLib via DebugLib, and requires us
to ensure that the baud clock is programmed correctly by the SEC phase.
Use this version of the library to satisfy all SerialPortLib dependencies
except the ones in PrePi and in SerialDxe. These will retain the full
version, which is the only one that still consumes PcdSerialClockRate.
[0] There are two distinct problems making this mess almost unsolvable:
- SerialPortInitialize() is called directly in various places instead
of relying on constructor ordering, so adding a constructor to a
SerialPortLib implementation does not help,
- Constructor ordering resolution in the EDK2 tooling fails to take
transitive dependencies into account if an intermediate library has
no constructor it self. For instance, if LibA depends on LibB, which
depends on LibC, the constructors of LibA and LibC could be called in
any order if LibB does not have a constructor itself (and fixing this
breaks all the platforms in the tree)
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Pete Batard <pete@akeo.ie>
Tested-by: Pete Batard <pete@akeo.ie>
Diffstat (limited to 'Platform/RaspberryPi/RPi3')
-rw-r--r-- | Platform/RaspberryPi/RPi3/RPi3.dsc | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/Platform/RaspberryPi/RPi3/RPi3.dsc b/Platform/RaspberryPi/RPi3/RPi3.dsc index 563fb891..d7218219 100644 --- a/Platform/RaspberryPi/RPi3/RPi3.dsc +++ b/Platform/RaspberryPi/RPi3/RPi3.dsc @@ -127,7 +127,7 @@ # Dual serial port library
PL011UartClockLib|ArmPlatformPkg/Library/PL011UartClockLib/PL011UartClockLib.inf
PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf
- SerialPortLib|Platform/RaspberryPi/Library/DualSerialPortLib/DualSerialPortLib.inf
+ SerialPortLib|Platform/RaspberryPi/Library/DualSerialPortLib/DebugDualSerialPortLib.inf
# Cryptographic libraries
IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
@@ -521,7 +521,10 @@ #
# PEI Phase modules
#
- ArmPlatformPkg/PrePi/PeiUniCore.inf
+ ArmPlatformPkg/PrePi/PeiUniCore.inf {
+ <LibraryClasses>
+ SerialPortLib|Platform/RaspberryPi/Library/DualSerialPortLib/DualSerialPortLib.inf
+ }
#
# DXE
@@ -569,7 +572,10 @@ MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
- MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+ MdeModulePkg/Universal/SerialDxe/SerialDxe.inf {
+ <LibraryClasses>
+ SerialPortLib|Platform/RaspberryPi/Library/DualSerialPortLib/DualSerialPortLib.inf
+ }
Platform/RaspberryPi/Drivers/DisplayDxe/DisplayDxe.inf
MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
|