From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-io1-f47.google.com (mail-io1-f47.google.com [209.85.166.47]) by mx.groups.io with SMTP id smtpd.web11.229.1643407370286292154 for ; Fri, 28 Jan 2022 14:02:50 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20210112 header.b=KSsiOPHt; spf=pass (domain: gmail.com, ip: 209.85.166.47, mailfrom: benjamin.doron00@gmail.com) Received: by mail-io1-f47.google.com with SMTP id z199so9482042iof.10 for ; Fri, 28 Jan 2022 14:02:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=Or4Gmqe/0f8K9xk3wujfFM8GUSrC7nyO3c6FnNATQf4=; b=KSsiOPHtNlKM20O/bkN22MsZLc1rTFpMBQbI5IZVLvfxTxBC224wqkGNEWkWppDjPF WFFGuY3o+Qo+0ojbVsR5PjMw6NUnvPSyQK7CSYhRwL+rgeETOtaceJAmjHBUNcWn7FYo BKnoUm4hHZvQuEu0KNDzqhtll2aCtqB1bLxAPFcBIF3ltq++WvjO0dbqg+sAIwZj0GMK esu7ma6Oz2KEmubE2jJS7ywZw5oWR02if24Dgck70SldsxVlEIuAj0EVJWF2f0NgyjMM 3diYBQD52M5fIs+8H/Zp/2M7JJHOdCLpBP0a7sc5tzlmm17nVMPuQTL0KbrliIhlJJwQ lOWA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=Or4Gmqe/0f8K9xk3wujfFM8GUSrC7nyO3c6FnNATQf4=; b=DUcCWYR0sTnvHaPDP3YnYFeJjcrHOCYK8uahjo+YPmlWRQloX/P8ZlcG9HUsOauDvQ eK2M6otN4B2hJj3Qn/c+wDkjQbn14Bdfbad+XIWURIWDLQguqor2RtlTAm5BjD7sHLdE K/8KouRDbjXWH26/Ne9s4/4lqeeGpNE3fHs4Tjq4sKQMUWNAi8RwVyhLGejWCoAwDPpl 6EKSzY2X8qKWheWEPAQFk5OipBunIaFCUVBPdvwsdy+WfNAVaJMtENkHSiWQ5R+kJMWH ZABLMKLd9wfjsXxkpsCyqiiiii3pvEiaSEe4Mq1sy5ohxl5h3nSnOMbfKz7bsmZPy3MT 3ZZw== X-Gm-Message-State: AOAM533aZQoRei6FcyFWC6vTQzf6PhsfK0lKbhRZLG+A62fRlzlemOvC sspHMKNERRnWtvSTqtBSy3ZDdcEGjYFAxWXz6knn8KTa X-Google-Smtp-Source: ABdhPJxFlkvBbzm9EykHyWb3njiCW9SAbQZ0qwfRlj1qzxH8ZJajrOmKFEMNEUutBz5gsspT0ROY+lA0dJxugVQ7bLI= X-Received: by 2002:a5e:d610:: with SMTP id w16mr6089341iom.87.1643407369685; Fri, 28 Jan 2022 14:02:49 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: "Benjamin Doron" Date: Fri, 28 Jan 2022 17:02:36 -0500 Message-ID: Subject: Re: [PATCH] UefiPayloadPkg: Add support for logging to CBMEM console To: Sean Rhodes Cc: devel@edk2.groups.io Content-Type: multipart/alternative; boundary="0000000000007dce6605d6ab9897" --0000000000007dce6605d6ab9897 Content-Type: text/plain; charset="UTF-8" Hi, Thanks for looking at my patch. I probably need to refine the library before it's ready to be upstreamed. Two items on my list were finally debugging how to make `FindCbTag()` work, and using `CopyMem()` instead of byte-assignment. This commit is missing my follow-up: We must not define MDEPKG_NDEBUG or the messages are stripped. We must not make asserts fatal, because then they cannot be seen; we must try to continue anyways. PlatformHookLibNull must be used, or asserts occur when UefiPayload's instance cannot find the serial table in CBMEM. See https://github.com/MrChromebox/edk2/commit/5fec6d995cc2f453d4b580e941fca6662e2ed367 for the updated commit, I don't believe it ever made it to my GitHub. However, I now know that the Status Code stuff is irrelevant, because we aren't logging through its infrastructure. That should be it, I suppose? I'll get back to it when I can if upstream/coreboot's fork wants. Regards, Benjamin On Fri., Jan. 28, 2022, 4:38 p.m. Sean Rhodes, wrote: > From: Benjamin Doron > > Tested on QEMU, dumping the appropriate memory region in UEFI shell > shows the TianoCore log. `find_cb_subtable` is sourced from STM/SeaBIOS. > > Signed-off-by: Benjamin Doron > --- > UefiPayloadPkg/Include/Coreboot.h | 14 + > .../Library/CbSerialPortLib/CbSerialPortLib.c | 272 ++++++++++++++++++ > .../CbSerialPortLib/CbSerialPortLib.inf | 27 ++ > UefiPayloadPkg/UefiPayloadPkg.dsc | 5 + > UefiPayloadPkg/UefiPayloadPkg.fdf | 6 +- > 5 files changed, 323 insertions(+), 1 deletion(-) > create mode 100644 > UefiPayloadPkg/Library/CbSerialPortLib/CbSerialPortLib.c > create mode 100644 > UefiPayloadPkg/Library/CbSerialPortLib/CbSerialPortLib.inf > > diff --git a/UefiPayloadPkg/Include/Coreboot.h > b/UefiPayloadPkg/Include/Coreboot.h > index a3e1109fe8..f2f577a02e 100644 > --- a/UefiPayloadPkg/Include/Coreboot.h > +++ b/UefiPayloadPkg/Include/Coreboot.h > @@ -199,7 +199,14 @@ struct cb_forward { > UINT64 forward; > }; > > +struct cb_cbmem_ref { > + UINT32 tag; > + UINT32 size; > + UINT64 cbmem_addr; > +}; > + > #define CB_TAG_FRAMEBUFFER 0x0012 > + > struct cb_framebuffer { > UINT32 tag; > UINT32 size; > @@ -230,6 +237,13 @@ struct cb_vdat { > #define CB_TAG_TIMESTAMPS 0x0016 > #define CB_TAG_CBMEM_CONSOLE 0x0017 > #define CB_TAG_MRC_CACHE 0x0018 > + > +struct cbmem_console { > + UINT32 size; > + UINT32 cursor; > + UINT8 body[0]; > +} __attribute__((packed)); > + > struct cb_cbmem_tab { > UINT32 tag; > UINT32 size; > diff --git a/UefiPayloadPkg/Library/CbSerialPortLib/CbSerialPortLib.c > b/UefiPayloadPkg/Library/CbSerialPortLib/CbSerialPortLib.c > new file mode 100644 > index 0000000000..7b26c08dd7 > --- /dev/null > +++ b/UefiPayloadPkg/Library/CbSerialPortLib/CbSerialPortLib.c > @@ -0,0 +1,272 @@ > +/** @file > + CBMEM console SerialPortLib instance > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include > +#include > + > +#include > +#include > +#include > + > +// > +// We can't use DebugLib due to a constructor dependency cycle between > DebugLib > +// and ourselves. > +// > +#define ASSERT(Expression) \ > + do { \ > + if (!(Expression)) { \ > + CpuDeadLoop (); \ > + } \ > + } while (FALSE) > + > +#define CBMC_CURSOR_MASK ((1 << 28) - 1) > +#define CBMC_OVERFLOW (1 << 31) > + > +STATIC struct cbmem_console *gCbConsole = NULL; > +STATIC UINT32 STM_cursor = 0; > + > +// Try to find the coreboot memory table in the given coreboot table. > +static void * > +find_cb_subtable(struct cb_header *cbh, UINT32 tag) > +{ > + char *tbl = (char *)cbh + sizeof(*cbh); > + UINT32 count = cbh->table_entries; > + int i; > + for (i=0; i + struct cb_memory *cbm = (void*)tbl; > + tbl += cbm->size; > + if (cbm->tag == tag) > + return cbm; > + } > + return NULL; > +} > + > +/** > + Initialize the serial device hardware. > + > + If no initialization is required, then return RETURN_SUCCESS. > + If the serial device was successfully initialized, then return > RETURN_SUCCESS. > + If the serial device could not be initialized, then return > RETURN_DEVICE_ERROR. > + > + @retval RETURN_SUCCESS The serial device was initialized. > + @retval RETURN_DEVICE_ERROR The serial device could not be > initialized. > + > +**/ > +RETURN_STATUS > +EFIAPI > +SerialPortInitialize ( > + VOID > + ) > +{ > + /* `FindCbTag` doesn't work because we need direct access to the memory > addresses? */ > + struct cb_header *cbh = GetParameterBase(); > + if (!cbh) { > + return RETURN_DEVICE_ERROR; > + } > + > + struct cb_cbmem_ref *cbref = find_cb_subtable(cbh, > CB_TAG_CBMEM_CONSOLE); > + if (!cbref) { > + return RETURN_DEVICE_ERROR; > + } > + > + gCbConsole = (void *)(UINTN)cbref->cbmem_addr; // Support PEI and > DXE > + if (gCbConsole == NULL) { > + return RETURN_DEVICE_ERROR; > + } > + > + // set the cursor such that the STM console will not overwrite the > + // coreboot console output > + STM_cursor = gCbConsole->cursor & CBMC_CURSOR_MASK; > + > + return RETURN_SUCCESS; > +} > + > +/** > + Write data from buffer to serial device. > + > + Writes NumberOfBytes data bytes from Buffer to the serial device. > + The number of bytes actually written to the serial device is returned. > + If the return value is less than NumberOfBytes, then the write > operation failed. > + If Buffer is NULL, then ASSERT(). > + If NumberOfBytes is zero, then return 0. > + > + @param Buffer Pointer to the data buffer to be written. > + @param NumberOfBytes Number of bytes to written to the serial > device. > + > + @retval 0 NumberOfBytes is 0. > + @retval >0 The number of bytes written to the serial > device. > + If this value is less than NumberOfBytes, then > the write operation failed. > + > +**/ > +UINTN > +EFIAPI > +SerialPortWrite ( > + IN UINT8 *Buffer, > + IN UINTN NumberOfBytes > + ) > +{ > + UINTN Sent; > + UINT32 cursor; > + UINT32 flags; > + > + ASSERT (Buffer != NULL); > + > + if (NumberOfBytes == 0) { > + return 0; > + } > + > + if (!gCbConsole) { > + return 0; > + } > + > + Sent = 0; > + do { > + cursor = gCbConsole->cursor & CBMC_CURSOR_MASK; > + flags = gCbConsole->cursor & ~CBMC_CURSOR_MASK; > + > + if (cursor >= gCbConsole->size) { > + return 0; // Old coreboot version with legacy overflow > mechanism. > + } > + > + gCbConsole->body[cursor++] = Buffer[Sent++]; > + > + if (cursor >= gCbConsole->size) { > + cursor = STM_cursor; > + flags |= CBMC_OVERFLOW; > + } > + > + gCbConsole->cursor = flags | cursor; > + } while (Sent < NumberOfBytes); > + > + return Sent; > +} > + > +/** > + Read data from serial device and save the datas in buffer. > + > + Reads NumberOfBytes data bytes from a serial device into the buffer > + specified by Buffer. The number of bytes actually read is returned. > + If Buffer is NULL, then ASSERT(). > + If NumberOfBytes is zero, then return 0. > + > + @param Buffer Pointer to the data buffer to store the data > read from the serial device. > + @param NumberOfBytes Number of bytes which will be read. > + > + @retval 0 Read data failed, no data is to be read. > + @retval >0 Actual number of bytes read from serial device. > + > +**/ > +UINTN > +EFIAPI > +SerialPortRead ( > + OUT UINT8 *Buffer, > + IN UINTN NumberOfBytes > +) > +{ > + return 0; > +} > + > +/** > + Polls a serial device to see if there is any data waiting to be read. > + > + @retval TRUE Data is waiting to be read from the serial > device. > + @retval FALSE There is no data waiting to be read from the > serial device. > + > +**/ > +BOOLEAN > +EFIAPI > +SerialPortPoll ( > + VOID > + ) > +{ > + return FALSE; > +} > + > +/** > + Sets the control bits on a serial device. > + > + @param Control Sets the bits of Control that are > settable. > + > + @retval RETURN_SUCCESS The new control bits were set on the > serial device. > + @retval RETURN_UNSUPPORTED The serial device does not support this > operation. > + @retval RETURN_DEVICE_ERROR The serial device is not functioning > correctly. > + > +**/ > +RETURN_STATUS > +EFIAPI > +SerialPortSetControl ( > + IN UINT32 Control > + ) > +{ > + return RETURN_UNSUPPORTED; > +} > + > +/** > + Retrieve the status of the control bits on a serial device. > + > + @param Control A pointer to return the current control > signals from the serial device. > + > + @retval RETURN_SUCCESS The control bits were read from the > serial device. > + @retval RETURN_UNSUPPORTED The serial device does not support this > operation. > + @retval RETURN_DEVICE_ERROR The serial device is not functioning > correctly. > + > +**/ > +RETURN_STATUS > +EFIAPI > +SerialPortGetControl ( > + OUT UINT32 *Control > + ) > +{ > + return RETURN_UNSUPPORTED; > +} > + > +/** > + Sets the baud rate, receive FIFO depth, transmit/receive time out, > parity, > + data bits, and stop bits on a serial device. > + > + @param BaudRate The requested baud rate. A BaudRate value of > 0 will use the > + device's default interface speed. > + On output, the value actually set. > + @param ReceiveFifoDepth The requested depth of the FIFO on the > receive side of the > + serial interface. A ReceiveFifoDepth value of > 0 will use > + the device's default FIFO depth. > + On output, the value actually set. > + @param Timeout The requested time out for a single character > in microseconds. > + This timeout applies to both the transmit and > receive side of the > + interface. A Timeout value of 0 will use the > device's default time > + out value. > + On output, the value actually set. > + @param Parity The type of parity to use on this serial > device. A Parity value of > + DefaultParity will use the device's default > parity value. > + On output, the value actually set. > + @param DataBits The number of data bits to use on the serial > device. A DataBits > + value of 0 will use the device's default data > bit setting. > + On output, the value actually set. > + @param StopBits The number of stop bits to use on this serial > device. A StopBits > + value of DefaultStopBits will use the > device's default number of > + stop bits. > + On output, the value actually set. > + > + @retval RETURN_SUCCESS The new attributes were set on the > serial device. > + @retval RETURN_UNSUPPORTED The serial device does not support > this operation. > + @retval RETURN_INVALID_PARAMETER One or more of the attributes has an > unsupported value. > + @retval RETURN_DEVICE_ERROR The serial device is not functioning > correctly. > + > +**/ > +RETURN_STATUS > +EFIAPI > +SerialPortSetAttributes ( > + IN OUT UINT64 *BaudRate, > + IN OUT UINT32 *ReceiveFifoDepth, > + IN OUT UINT32 *Timeout, > + IN OUT EFI_PARITY_TYPE *Parity, > + IN OUT UINT8 *DataBits, > + IN OUT EFI_STOP_BITS_TYPE *StopBits > + ) > +{ > + return RETURN_UNSUPPORTED; > +} > diff --git a/UefiPayloadPkg/Library/CbSerialPortLib/CbSerialPortLib.inf > b/UefiPayloadPkg/Library/CbSerialPortLib/CbSerialPortLib.inf > new file mode 100644 > index 0000000000..37b33c24ad > --- /dev/null > +++ b/UefiPayloadPkg/Library/CbSerialPortLib/CbSerialPortLib.inf > @@ -0,0 +1,27 @@ > +## @file > +# Component description file for CbSerialPortLib module. > +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > + INF_VERSION = 0x00010005 > + BASE_NAME = CbSerialPortLib > + FILE_GUID = 0DB3EF12-1426-4086-B012-113184C4CE11 > + MODULE_TYPE = BASE > + VERSION_STRING = 0.5 > + LIBRARY_CLASS = SerialPortLib > + CONSTRUCTOR = SerialPortInitialize > + > +[Sources] > + CbSerialPortLib.c > + > +[Packages] > + MdeModulePkg/MdeModulePkg.dec > + MdePkg/MdePkg.dec > + UefiPayloadPkg/UefiPayloadPkg.dec > + > +[LibraryClasses] > + BaseLib > + BlParseLib > diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc > b/UefiPayloadPkg/UefiPayloadPkg.dsc > index 3d08edfe31..b3770b9be6 100644 > --- a/UefiPayloadPkg/UefiPayloadPkg.dsc > +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc > @@ -33,6 +33,7 @@ > DEFINE UNIVERSAL_PAYLOAD = FALSE > DEFINE SECURITY_STUB_ENABLE = TRUE > DEFINE SMM_SUPPORT = FALSE > + DEFINE USE_CBMEM_FOR_CONSOLE = FALSE > # > # SBL: UEFI payload for Slim Bootloader > # COREBOOT: UEFI payload for coreboot > @@ -223,7 +224,11 @@ > TimerLib|UefiPayloadPkg/Library/AcpiTimerLib/AcpiTimerLib.inf > !endif > ResetSystemLib|UefiPayloadPkg/Library/ResetSystemLib/ResetSystemLib.inf > +!if $(USE_CBMEM_FOR_CONSOLE) == TRUE > + SerialPortLib|UefiPayloadPkg/Library/CbSerialPortLib/CbSerialPortLib.inf > +!else > > SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf > +!endif > > PlatformHookLib|UefiPayloadPkg/Library/PlatformHookLib/PlatformHookLib.inf > > PlatformBootManagerLib|UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf > IoApicLib|PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf > diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf > b/UefiPayloadPkg/UefiPayloadPkg.fdf > index f619a23139..0df8342252 100644 > --- a/UefiPayloadPkg/UefiPayloadPkg.fdf > +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf > @@ -15,8 +15,12 @@ DEFINE FD_BLOCK_SIZE = 0x00001000 > !if $(TARGET) == "NOOPT" > DEFINE FD_SIZE = 0x00850000 > DEFINE NUM_BLOCKS = 0x850 > -!else > > +!elseif $(USE_CBMEM_FOR_CONSOLE) == TRUE > +DEFINE FD_SIZE = 0x00600000 > +DEFINE NUM_BLOCKS = 0x600 > + > +!else > DEFINE FD_SIZE = 0x00590000 > DEFINE NUM_BLOCKS = 0x590 > !endif > -- > 2.32.0 > > --0000000000007dce6605d6ab9897 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi,
Thanks for l= ooking at my patch.

I probably need t= o refine the library before it's ready to be upstreamed. Two items on m= y list were finally debugging how to make `FindCbTag()` work, and using `Co= pyMem()` instead of byte-assignment.

This commit is missing my follow-up: We must not define MDEPKG= _NDEBUG or the messages are stripped. We must not make asserts fatal, becau= se then they cannot be seen; we must try to continue anyways. PlatformHookL= ibNull must be used, or asserts occur when UefiPayload's instance canno= t find the serial table in CBMEM. See=C2=A0https://git= hub.com/MrChromebox/edk2/commit/5fec6d995cc2f453d4b580e941fca6662e2ed367 for the updated commit, I don't believe it ever made it to my GitHub.= However, I now know that the Status Code stuff is irrelevant, because we a= ren't logging through its infrastructure.

That should be it, I suppose? I'll get back to it= when I can if upstream/coreboot's fork wants.
<= br>
Regards,
Benjamin

On Fri., Jan. 28, 2022, 4:38 p.m. Sean Rhodes, <s= ean@starlabs.systems> wrote:
Fro= m: Benjamin Doron <benjamin.doron00@gmail.com>

Tested on QEMU, dumping the appropriate memory region in UEFI shell
shows the TianoCore log. `find_cb_subtable` is sourced from STM/SeaBIOS.
Signed-off-by: Benjamin Doron <benjamin.doron00@gmail.com>= ;
---
=C2=A0UefiPayloadPkg/Include/Coreboot.h=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0|=C2=A0 14 +
=C2=A0.../Library/CbSerialPortLib/CbSerialPortLib.c | 272 +++++++++++++++++= +
=C2=A0.../CbSerialPortLib/CbSerialPortLib.inf=C2=A0 =C2=A0 =C2=A0 =C2=A0|= =C2=A0 27 ++
=C2=A0UefiPayloadPkg/UefiPayloadPkg.dsc=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0|=C2=A0 =C2=A05 +
=C2=A0UefiPayloadPkg/UefiPayloadPkg.fdf=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0|=C2=A0 =C2=A06 +-
=C2=A05 files changed, 323 insertions(+), 1 deletion(-)
=C2=A0create mode 100644 UefiPayloadPkg/Library/CbSerialPortLib/CbSerialPor= tLib.c
=C2=A0create mode 100644 UefiPayloadPkg/Library/CbSerialPortLib/CbSerialPor= tLib.inf

diff --git a/UefiPayloadPkg/Include/Coreboot.h b/UefiPayloadPkg/Include/Cor= eboot.h
index a3e1109fe8..f2f577a02e 100644
--- a/UefiPayloadPkg/Include/Coreboot.h
+++ b/UefiPayloadPkg/Include/Coreboot.h
@@ -199,7 +199,14 @@ struct cb_forward {
=C2=A0 =C2=A0UINT64=C2=A0 =C2=A0 forward;
=C2=A0};

+struct cb_cbmem_ref {
+=C2=A0 UINT32 tag;
+=C2=A0 UINT32 size;
+=C2=A0 UINT64 cbmem_addr;
+};
+
=C2=A0#define CB_TAG_FRAMEBUFFER=C2=A0 0x0012
+
=C2=A0struct cb_framebuffer {
=C2=A0 =C2=A0UINT32=C2=A0 =C2=A0 tag;
=C2=A0 =C2=A0UINT32=C2=A0 =C2=A0 size;
@@ -230,6 +237,13 @@ struct cb_vdat {
=C2=A0#define CB_TAG_TIMESTAMPS=C2=A0 =C2=A0 =C2=A00x0016
=C2=A0#define CB_TAG_CBMEM_CONSOLE=C2=A0 0x0017
=C2=A0#define CB_TAG_MRC_CACHE=C2=A0 =C2=A0 =C2=A0 0x0018
+
+struct cbmem_console {
+=C2=A0 UINT32 size;
+=C2=A0 UINT32 cursor;
+=C2=A0 UINT8=C2=A0 body[0];
+} __attribute__((packed));
+
=C2=A0struct cb_cbmem_tab {
=C2=A0 =C2=A0UINT32=C2=A0 =C2=A0 tag;
=C2=A0 =C2=A0UINT32=C2=A0 =C2=A0 size;
diff --git a/UefiPayloadPkg/Library/CbSerialPortLib/CbSerialPortLib.c b/Uef= iPayloadPkg/Library/CbSerialPortLib/CbSerialPortLib.c
new file mode 100644
index 0000000000..7b26c08dd7
--- /dev/null
+++ b/UefiPayloadPkg/Library/CbSerialPortLib/CbSerialPortLib.c
@@ -0,0 +1,272 @@
+/** @file
+=C2=A0 CBMEM console SerialPortLib instance
+
+=C2=A0 SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include <Coreboot.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BlParseLib.h>
+#include <Library/SerialPortLib.h>
+
+//
+// We can't use DebugLib due to a constructor dependency cycle between= DebugLib
+// and ourselves.
+//
+#define ASSERT(Expression)=C2=A0 =C2=A0 =C2=A0 \
+=C2=A0 do {=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 \
+=C2=A0 =C2=A0 if (!(Expression)) {=C2=A0 =C2=A0 =C2=A0 =C2=A0 \
+=C2=A0 =C2=A0 =C2=A0 CpuDeadLoop ();=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0\
+=C2=A0 =C2=A0 }=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0\
+=C2=A0 } while (FALSE)
+
+#define CBMC_CURSOR_MASK ((1 << 28) - 1)
+#define CBMC_OVERFLOW (1 << 31)
+
+STATIC struct cbmem_console=C2=A0 *gCbConsole =3D NULL;
+STATIC UINT32 STM_cursor =3D 0;
+
+// Try to find the coreboot memory table in the given coreboot table.
+static void *
+find_cb_subtable(struct cb_header *cbh, UINT32 tag)
+{
+=C2=A0 char *tbl =3D (char *)cbh + sizeof(*cbh);
+=C2=A0 UINT32 count =3D cbh->table_entries;
+=C2=A0 int i;
+=C2=A0 for (i=3D0; i<count; i++) {
+=C2=A0 =C2=A0 struct cb_memory *cbm =3D (void*)tbl;
+=C2=A0 =C2=A0 tbl +=3D cbm->size;
+=C2=A0 =C2=A0 if (cbm->tag =3D=3D tag)
+=C2=A0 =C2=A0 =C2=A0 return cbm;
+=C2=A0 }
+=C2=A0 =C2=A0 return NULL;
+}
+
+/**
+=C2=A0 Initialize the serial device hardware.
+
+=C2=A0 If no initialization is required, then return RETURN_SUCCESS.
+=C2=A0 If the serial device was successfully initialized, then return RETU= RN_SUCCESS.
+=C2=A0 If the serial device could not be initialized, then return RETURN_D= EVICE_ERROR.
+
+=C2=A0 @retval RETURN_SUCCESS=C2=A0 =C2=A0 =C2=A0 =C2=A0 The serial device= was initialized.
+=C2=A0 @retval RETURN_DEVICE_ERROR=C2=A0 =C2=A0The serial device could not= be initialized.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortInitialize (
+=C2=A0 VOID
+=C2=A0 )
+{
+=C2=A0 /* `FindCbTag` doesn't work because we need direct access to th= e memory addresses? */
+=C2=A0 struct cb_header *cbh =3D GetParameterBase();
+=C2=A0 if (!cbh) {
+=C2=A0 =C2=A0 return RETURN_DEVICE_ERROR;
+=C2=A0 }
+
+=C2=A0 struct cb_cbmem_ref *cbref =3D find_cb_subtable(cbh, CB_TAG_CBMEM_C= ONSOLE);
+=C2=A0 if (!cbref) {
+=C2=A0 =C2=A0 return RETURN_DEVICE_ERROR;
+=C2=A0 }
+
+=C2=A0 gCbConsole =3D (void *)(UINTN)cbref->cbmem_addr;=C2=A0 =C2=A0 = =C2=A0 =C2=A0// Support PEI and DXE
+=C2=A0 if (gCbConsole =3D=3D NULL) {
+=C2=A0 =C2=A0 return RETURN_DEVICE_ERROR;
+=C2=A0 }
+
+=C2=A0 // set the cursor such that the STM console will not overwrite the<= br> +=C2=A0 // coreboot console output
+=C2=A0 STM_cursor =3D gCbConsole->cursor & CBMC_CURSOR_MASK;
+
+=C2=A0 return RETURN_SUCCESS;
+}
+
+/**
+=C2=A0 Write data from buffer to serial device.
+
+=C2=A0 Writes NumberOfBytes data bytes from Buffer to the serial device. +=C2=A0 The number of bytes actually written to the serial device is return= ed.
+=C2=A0 If the return value is less than NumberOfBytes, then the write oper= ation failed.
+=C2=A0 If Buffer is NULL, then ASSERT().
+=C2=A0 If NumberOfBytes is zero, then return 0.
+
+=C2=A0 @param=C2=A0 Buffer=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Pointer= to the data buffer to be written.
+=C2=A0 @param=C2=A0 NumberOfBytes=C2=A0 =C2=A0 Number of bytes to written = to the serial device.
+
+=C2=A0 @retval 0=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Nu= mberOfBytes is 0.
+=C2=A0 @retval >0=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0The number of bytes written to the serial device.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0If this value is less than NumberOfBytes, then the = write operation failed.
+
+**/
+UINTN
+EFIAPI
+SerialPortWrite (
+=C2=A0 IN UINT8=C2=A0 =C2=A0 =C2=A0*Buffer,
+=C2=A0 IN UINTN=C2=A0 =C2=A0 =C2=A0NumberOfBytes
+=C2=A0 )
+{
+=C2=A0 UINTN=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Sent;
+=C2=A0 UINT32=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 cursor;
+=C2=A0 UINT32=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 flags;
+
+=C2=A0 ASSERT (Buffer !=3D NULL);
+
+=C2=A0 if (NumberOfBytes =3D=3D 0) {
+=C2=A0 =C2=A0 return 0;
+=C2=A0 }
+
+=C2=A0 if (!gCbConsole) {
+=C2=A0 =C2=A0 return 0;
+=C2=A0 }
+
+=C2=A0 Sent =3D 0;
+=C2=A0 do {
+=C2=A0 =C2=A0 cursor =3D gCbConsole->cursor & CBMC_CURSOR_MASK;
+=C2=A0 =C2=A0 flags =3D gCbConsole->cursor & ~CBMC_CURSOR_MASK;
+
+=C2=A0 =C2=A0 if (cursor >=3D gCbConsole->size) {
+=C2=A0 =C2=A0 =C2=A0 return 0;=C2=A0 =C2=A0 =C2=A0 =C2=A0 // Old coreboot = version with legacy overflow mechanism.
+=C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 gCbConsole->body[cursor++] =3D Buffer[Sent++];
+
+=C2=A0 =C2=A0 if (cursor >=3D gCbConsole->size) {
+=C2=A0 =C2=A0 =C2=A0 cursor =3D STM_cursor;
+=C2=A0 =C2=A0 =C2=A0 flags |=3D CBMC_OVERFLOW;
+=C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 gCbConsole->cursor =3D flags | cursor;
+=C2=A0 } while (Sent < NumberOfBytes);
+
+=C2=A0 return Sent;
+}
+
+/**
+=C2=A0 Read data from serial device and save the datas in buffer.
+
+=C2=A0 Reads NumberOfBytes data bytes from a serial device into the buffer=
+=C2=A0 specified by Buffer. The number of bytes actually read is returned.=
+=C2=A0 If Buffer is NULL, then ASSERT().
+=C2=A0 If NumberOfBytes is zero, then return 0.
+
+=C2=A0 @param=C2=A0 Buffer=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Pointer= to the data buffer to store the data read from the serial device.
+=C2=A0 @param=C2=A0 NumberOfBytes=C2=A0 =C2=A0 Number of bytes which will = be read.
+
+=C2=A0 @retval 0=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Re= ad data failed, no data is to be read.
+=C2=A0 @retval >0=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0Actual number of bytes read from serial device.
+
+**/
+UINTN
+EFIAPI
+SerialPortRead (
+=C2=A0 OUT UINT8=C2=A0 =C2=A0 =C2=A0*Buffer,
+=C2=A0 IN=C2=A0 UINTN=C2=A0 =C2=A0 =C2=A0NumberOfBytes
+)
+{
+=C2=A0 return 0;
+}
+
+/**
+=C2=A0 Polls a serial device to see if there is any data waiting to be rea= d.
+
+=C2=A0 @retval TRUE=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Data is= waiting to be read from the serial device.
+=C2=A0 @retval FALSE=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 There is no = data waiting to be read from the serial device.
+
+**/
+BOOLEAN
+EFIAPI
+SerialPortPoll (
+=C2=A0 VOID
+=C2=A0 )
+{
+=C2=A0 return FALSE;
+}
+
+/**
+=C2=A0 Sets the control bits on a serial device.
+
+=C2=A0 @param Control=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 Sets the bits of Control that are settable.
+
+=C2=A0 @retval RETURN_SUCCESS=C2=A0 =C2=A0 =C2=A0 =C2=A0 The new control b= its were set on the serial device.
+=C2=A0 @retval RETURN_UNSUPPORTED=C2=A0 =C2=A0 The serial device does not = support this operation.
+=C2=A0 @retval RETURN_DEVICE_ERROR=C2=A0 =C2=A0The serial device is not fu= nctioning correctly.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortSetControl (
+=C2=A0 IN UINT32 Control
+=C2=A0 )
+{
+=C2=A0 return RETURN_UNSUPPORTED;
+}
+
+/**
+=C2=A0 Retrieve the status of the control bits on a serial device.
+
+=C2=A0 @param Control=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 A pointer to return the current control signals from the serial device.=
+
+=C2=A0 @retval RETURN_SUCCESS=C2=A0 =C2=A0 =C2=A0 =C2=A0 The control bits = were read from the serial device.
+=C2=A0 @retval RETURN_UNSUPPORTED=C2=A0 =C2=A0 The serial device does not = support this operation.
+=C2=A0 @retval RETURN_DEVICE_ERROR=C2=A0 =C2=A0The serial device is not fu= nctioning correctly.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortGetControl (
+=C2=A0 OUT UINT32 *Control
+=C2=A0 )
+{
+=C2=A0 return RETURN_UNSUPPORTED;
+}
+
+/**
+=C2=A0 Sets the baud rate, receive FIFO depth, transmit/receive time out, = parity,
+=C2=A0 data bits, and stop bits on a serial device.
+
+=C2=A0 @param BaudRate=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0The request= ed baud rate. A BaudRate value of 0 will use the
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 device's default interface speed.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 On output, the value actually set.
+=C2=A0 @param ReceiveFifoDepth=C2=A0 =C2=A0The requested depth of the FIFO= on the receive side of the
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 serial interface. A ReceiveFifoDepth value of 0 wi= ll use
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 the device's default FIFO depth.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 On output, the value actually set.
+=C2=A0 @param Timeout=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 The request= ed time out for a single character in microseconds.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 This timeout applies to both the transmit and rece= ive side of the
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 interface. A Timeout value of 0 will use the devic= e's default time
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 out value.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 On output, the value actually set.
+=C2=A0 @param Parity=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0The ty= pe of parity to use on this serial device. A Parity value of
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 DefaultParity will use the device's default pa= rity value.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 On output, the value actually set.
+=C2=A0 @param DataBits=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0The number = of data bits to use on the serial device. A DataBits
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 value of 0 will use the device's default data = bit setting.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 On output, the value actually set.
+=C2=A0 @param StopBits=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0The number = of stop bits to use on this serial device. A StopBits
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 value of DefaultStopBits will use the device's= default number of
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 stop bits.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 On output, the value actually set.
+
+=C2=A0 @retval RETURN_SUCCESS=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 The= new attributes were set on the serial device.
+=C2=A0 @retval RETURN_UNSUPPORTED=C2=A0 =C2=A0 =C2=A0 =C2=A0 The serial de= vice does not support this operation.
+=C2=A0 @retval RETURN_INVALID_PARAMETER=C2=A0 One or more of the attribute= s has an unsupported value.
+=C2=A0 @retval RETURN_DEVICE_ERROR=C2=A0 =C2=A0 =C2=A0 =C2=A0The serial de= vice is not functioning correctly.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortSetAttributes (
+=C2=A0 IN OUT UINT64=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0*BaudR= ate,
+=C2=A0 IN OUT UINT32=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0*Recei= veFifoDepth,
+=C2=A0 IN OUT UINT32=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0*Timeo= ut,
+=C2=A0 IN OUT EFI_PARITY_TYPE=C2=A0 =C2=A0 *Parity,
+=C2=A0 IN OUT UINT8=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 *DataB= its,
+=C2=A0 IN OUT EFI_STOP_BITS_TYPE *StopBits
+=C2=A0 )
+{
+=C2=A0 return RETURN_UNSUPPORTED;
+}
diff --git a/UefiPayloadPkg/Library/CbSerialPortLib/CbSerialPortLib.inf b/U= efiPayloadPkg/Library/CbSerialPortLib/CbSerialPortLib.inf
new file mode 100644
index 0000000000..37b33c24ad
--- /dev/null
+++ b/UefiPayloadPkg/Library/CbSerialPortLib/CbSerialPortLib.inf
@@ -0,0 +1,27 @@
+## @file
+#=C2=A0 Component description file for CbSerialPortLib module.
+#
+#=C2=A0 SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+=C2=A0 INF_VERSION=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =3D 0x00010005
+=C2=A0 BASE_NAME=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =3D CbSerialPortLib
+=C2=A0 FILE_GUID=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =3D 0DB3EF12-1426-4086-B012-113184C4CE11
+=C2=A0 MODULE_TYPE=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =3D BASE
+=C2=A0 VERSION_STRING=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0=3D 0.5
+=C2=A0 LIBRARY_CLASS=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =3D SerialPortLib
+=C2=A0 CONSTRUCTOR=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =3D SerialPortInitialize
+
+[Sources]
+=C2=A0 CbSerialPortLib.c
+
+[Packages]
+=C2=A0 MdeModulePkg/MdeModulePkg.dec
+=C2=A0 MdePkg/MdePkg.dec
+=C2=A0 UefiPayloadPkg/UefiPayloadPkg.dec
+
+[LibraryClasses]
+=C2=A0 BaseLib
+=C2=A0 BlParseLib
diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayload= Pkg.dsc
index 3d08edfe31..b3770b9be6 100644
--- a/UefiPayloadPkg/UefiPayloadPkg.dsc
+++ b/UefiPayloadPkg/UefiPayloadPkg.dsc
@@ -33,6 +33,7 @@
=C2=A0 =C2=A0DEFINE UNIVERSAL_PAYLOAD=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =3D FALSE
=C2=A0 =C2=A0DEFINE SECURITY_STUB_ENABLE=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =3D TRUE
=C2=A0 =C2=A0DEFINE SMM_SUPPORT=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =3D FALSE
+=C2=A0 DEFINE USE_CBMEM_FOR_CONSOLE=C2=A0 =C2=A0 =C2=A0 =C2=A0 =3D FALSE =C2=A0 =C2=A0#
=C2=A0 =C2=A0# SBL:=C2=A0 =C2=A0 =C2=A0 UEFI payload for Slim Bootloader =C2=A0 =C2=A0# COREBOOT: UEFI payload for coreboot
@@ -223,7 +224,11 @@
=C2=A0 =C2=A0TimerLib|UefiPayloadPkg/Library/AcpiTimerLib/AcpiTimerLib.inf<= br> =C2=A0!endif
=C2=A0 =C2=A0ResetSystemLib|UefiPayloadPkg/Library/ResetSystemLib/ResetSyst= emLib.inf
+!if $(USE_CBMEM_FOR_CONSOLE) =3D=3D TRUE
+=C2=A0 SerialPortLib|UefiPayloadPkg/Library/CbSerialPortLib/CbSerialPortLi= b.inf
+!else
=C2=A0 =C2=A0SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/Base= SerialPortLib16550.inf
+!endif
=C2=A0 =C2=A0PlatformHookLib|UefiPayloadPkg/Library/PlatformHookLib/Platfor= mHookLib.inf
=C2=A0 =C2=A0PlatformBootManagerLib|UefiPayloadPkg/Library/PlatformBootMana= gerLib/PlatformBootManagerLib.inf
=C2=A0 =C2=A0IoApicLib|PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.i= nf
diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayload= Pkg.fdf
index f619a23139..0df8342252 100644
--- a/UefiPayloadPkg/UefiPayloadPkg.fdf
+++ b/UefiPayloadPkg/UefiPayloadPkg.fdf
@@ -15,8 +15,12 @@ DEFINE FD_BLOCK_SIZE =3D 0x00001000
=C2=A0!if $(TARGET) =3D=3D "NOOPT"
=C2=A0DEFINE FD_SIZE=C2=A0 =C2=A0 =C2=A0=3D 0x00850000
=C2=A0DEFINE NUM_BLOCKS=C2=A0 =3D 0x850
-!else

+!elseif $(USE_CBMEM_FOR_CONSOLE) =3D=3D TRUE
+DEFINE FD_SIZE=C2=A0 =C2=A0 =C2=A0=3D 0x00600000
+DEFINE NUM_BLOCKS=C2=A0 =3D 0x600
+
+!else
=C2=A0DEFINE FD_SIZE=C2=A0 =C2=A0 =C2=A0=3D 0x00590000
=C2=A0DEFINE NUM_BLOCKS=C2=A0 =3D 0x590
=C2=A0!endif
--
2.32.0

--0000000000007dce6605d6ab9897--