OvmfPkg/PlatformDebugLibIoPort: fix port detection for use in the DXE Core

The DXE Core is one of those modules that call
ProcessLibraryConstructorList() manually.

Before DxeMain() [MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c] calls
ProcessLibraryConstructorList(), and through it, our
PlatformDebugLibIoPortConstructor() function, DxeMain() invokes the
DEBUG() macro multiple times. That macro lands in our
PlatformDebugLibIoPortFound() function -- which currently relies on the
"mDebugIoPortFound" global variable that has (not yet) been set by the
constructor. As a result, early debug messages from the DXE Core are lost.

Move the device detection into PlatformDebugLibIoPortFound(), also caching
the fact (not just the result) of the device detection.

(We could introduce a separate DebugLib instance just for the DXE Core,
but the above approach works for all modules that currently consume the
PlatformDebugLibIoPort instance (which means "everything but SEC").)

This restores messages such as:

> CoreInitializeMemoryServices:
>   BaseAddress - 0x7AF21000 Length - 0x3CDE000 MinimalMemorySizeNeeded - 0x10F4000

Keep the empty constructor function -- OVMF's DebugLib instances have
always had constructors; we had better not upset constructor dependency
ordering by making our instance(s) constructor-less.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Fixes: c09d957130
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
[lersek@redhat.com: sanitize blank lines around "mDebugIoPortChecked"]
This commit is contained in:
Laszlo Ersek 2018-08-03 01:29:13 +02:00
parent d3bc33731f
commit 91a5b13650
1 changed files with 20 additions and 4 deletions

View File

@ -16,14 +16,26 @@
#include <Base.h> #include <Base.h>
#include "DebugLibDetect.h" #include "DebugLibDetect.h"
//
// Set to TRUE if the debug I/O port has been checked
//
STATIC BOOLEAN mDebugIoPortChecked = FALSE;
// //
// Set to TRUE if the debug I/O port is enabled // Set to TRUE if the debug I/O port is enabled
// //
STATIC BOOLEAN mDebugIoPortFound = FALSE; STATIC BOOLEAN mDebugIoPortFound = FALSE;
/** /**
This constructor function checks if the debug I/O port device is present, This constructor function must not do anything.
caching the result for later use.
Some modules consuming this library instance, such as the DXE Core, invoke
the DEBUG() macro before they explicitly call
ProcessLibraryConstructorList(). Therefore the auto-generated call from
ProcessLibraryConstructorList() to this constructor function may be preceded
by some calls to PlatformDebugLibIoPortFound() below. Hence
PlatformDebugLibIoPortFound() must not rely on anything this constructor
could set up.
@retval RETURN_SUCCESS The constructor always returns RETURN_SUCCESS. @retval RETURN_SUCCESS The constructor always returns RETURN_SUCCESS.
@ -34,12 +46,12 @@ PlatformDebugLibIoPortConstructor (
VOID VOID
) )
{ {
mDebugIoPortFound = PlatformDebugLibIoPortDetect();
return RETURN_SUCCESS; return RETURN_SUCCESS;
} }
/** /**
Return the cached result of detecting the debug I/O port device. At the first call, check if the debug I/O port device is present, and cache
the result for later use. At subsequent calls, return the cached result.
@retval TRUE if the debug I/O port device was detected. @retval TRUE if the debug I/O port device was detected.
@retval FALSE otherwise @retval FALSE otherwise
@ -51,5 +63,9 @@ PlatformDebugLibIoPortFound (
VOID VOID
) )
{ {
if (!mDebugIoPortChecked) {
mDebugIoPortFound = PlatformDebugLibIoPortDetect ();
mDebugIoPortChecked = TRUE;
}
return mDebugIoPortFound; return mDebugIoPortFound;
} }