From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-lj1-f177.google.com (mail-lj1-f177.google.com [209.85.208.177]) by mx.groups.io with SMTP id smtpd.web08.6493.1628344422014710191 for ; Sat, 07 Aug 2021 06:53:42 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@google.com header.s=20161025 header.b=prIKGPxo; spf=pass (domain: google.com, ip: 209.85.208.177, mailfrom: chengchieh@google.com) Received: by mail-lj1-f177.google.com with SMTP id l4so1716652ljq.4 for ; Sat, 07 Aug 2021 06:53:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=t92Jgllr6Yb2V5IM8VyV+iqImz255FKzNxBacRkwMgA=; b=prIKGPxoDsDuqTHBp0sLqnBQ8cUCDFFbWkZUnkdAvHmxm4DGH2P0N0DtzLxFU+g/3A +eu3s7IQ7l4j6dVHgxGpS/XSLzXpYW96M6i7xImm2g75hzehiTImcgQi2CrLEUbhVKc4 q39uqeRoUQq3JhazHPtFs0sTs7ZdZS5eGlBKyHd4RfqHz4DsVBiV5LT5cayHntfcfuZ2 Y28VF6js7SwKVRKO9GlR4EX5NKnRejR63psjbV0Ub/2uTSqd0al5VEkTaIQvDXVlVMku HkwuI3TQp7hta9POn/Pbl0qXmyfid6j7uTL8OFBOcN+TPc90naqXXG0Sv86d08si4j3u Bm0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=t92Jgllr6Yb2V5IM8VyV+iqImz255FKzNxBacRkwMgA=; b=hXmhI9fBog+nhOWQstz5Q29U5qOD2rq6jpi0D+OIQuaNzGqFQWLie5LVhCMg93ZqOa +IMkXHYDaYSlH7AzxmdgxjXLn+2zcvraiivSPnC7qBCiJSmKL0Y2y1pmVv3nP8I/XqzE 3uYNp8EPTPDRb9BtIfSjNVbKN/ldUpsSs/aYaZSyldZFHn3y47YB0yCvMSX3w1N1KIha 6uAylOcK52VwCn4bUz+qIC6pF7V3PR4RAloYUtPwymSoXIDsDHlaRdL9zxdXX0uXGtCi sw2dtFIZxaOADF+ZoLJJBho9J2Jp5nNP21IwiTjaTOpRVDJmIydNcdemzz4BX4+d1svq sQ9g== X-Gm-Message-State: AOAM5311bIdpBV5daL8VEqjiiKvJ+2IDQ35lNCNLB/ZVCTBcnbprrksK yqnAt4+EbuYNBSvI9CALbNiRDt6chePf0ag+AOhi4g== X-Google-Smtp-Source: ABdhPJyzZsYicHXgOchs6xQsMW1uEwiuBqOuKS9Drvoi6/xDvwfLn8NyYEyBHueIY4lNdJKcufWVvv5G2p4YxGx0Owk= X-Received: by 2002:a05:651c:93:: with SMTP id 19mr9770493ljq.421.1628344420056; Sat, 07 Aug 2021 06:53:40 -0700 (PDT) MIME-Version: 1.0 References: <20210721132328.1415485-1-chengchieh@google.com> <20210721132328.1415485-7-chengchieh@google.com> In-Reply-To: From: Cheng-Chieh Huang Date: Sat, 7 Aug 2021 21:53:28 +0800 Message-ID: Subject: Re: [edk2-devel] [PATCH v1 6/6] UefiPayloadPkg: LinuxBoot: use a text format for the configuration block. To: "Dong, Guo" Cc: "devel@edk2.groups.io" , Trammell Hudson Content-Type: multipart/alternative; boundary="000000000000bb87d205c8f87a10" --000000000000bb87d205c8f87a10 Content-Type: text/plain; charset="UTF-8" Thanks for the information. I will drop this patch in Patch set v2 for now and work with Trammell to revise this patch to fit EDK2 style. -- Cheng-Chieh On Wed, Aug 4, 2021 at 11:00 AM Dong, Guo wrote: > > Please run BaseTools\Scripts\PatchCheck.py to make sure it passed the > check. > > Update LbParseLib.c following > https://edk2-docs.gitbook.io/edk-ii-c-coding-standards-specification/. > current code is more like Linux style. E.g. > +static uint64_t parse_int(const char* s, char** end) { > + UINT64 x; > > Removed unused comments > +//#include > +//#include > > > Thanks, > Guo > -----Original Message----- > From: devel@edk2.groups.io On Behalf Of > Cheng-Chieh Huang via groups.io > Sent: Wednesday, July 21, 2021 6:23 AM > To: devel@edk2.groups.io > Cc: Trammell Hudson ; Cheng-Chieh Huang < > chengchieh@google.com> > Subject: [edk2-devel] [PATCH v1 6/6] UefiPayloadPkg: LinuxBoot: use a text > format for the configuration block. > > From: Trammell Hudson > > This adds a text command line for the UefiPayloadPkg that uses a textual > magic number 'LnxBoot1' and a series of white-space separated > key=value[,value...] pairs for the parameters. > > The v1 binary configuration structure is used if it is present instead for > backwards compatability. > > Currently supported text command line arguments are are: > > * `serial=baud,base,width,type,hz,pci` > (only `baud` needs to be specified, the rest have reasonable > defaults) > > * `mem=start,end,type` > Types are based on `/sys/firmware/memmaps/*/types`: > 1 == "System RAM" > 3 == "ACPI Tables" > 4 == "ACPI Non-volatile Storage" > 5 == "Reserved" > > * `ACPI20=base` pointer to RDSP (from `/sys/firmware/efi/systab`) > > * `SMBIOS=base` pointer to the SMBIOS table (also from the EFI table) > > Signed-off-by: Cheng-Chieh Huang > --- > UefiPayloadPkg/Include/Linuxboot.h | 17 +- > UefiPayloadPkg/Library/LbParseLib/LbParseLib.c | 252 +++++++++++++++++--- > 2 files changed, 230 insertions(+), 39 deletions(-) > > diff --git a/UefiPayloadPkg/Include/Linuxboot.h > b/UefiPayloadPkg/Include/Linuxboot.h > index 34ca18069983..56b39b5a09ff 100644 > --- a/UefiPayloadPkg/Include/Linuxboot.h > +++ b/UefiPayloadPkg/Include/Linuxboot.h > @@ -24,8 +24,7 @@ typedef struct MemoryMapEntryStruct { > UINT32 Type; > } MemoryMapEntry; > > -typedef struct UefiPayloadConfigStruct { > - UINT64 Version; > +typedef struct { > UINT64 AcpiBase; > UINT64 AcpiSize; > UINT64 SmbiosBase; > @@ -33,10 +32,22 @@ typedef struct UefiPayloadConfigStruct { > SerialPortConfig SerialConfig; > UINT32 NumMemoryMapEntries; > MemoryMapEntry MemoryMapEntries[0]; > +} UefiPayloadConfigV1; > + > +typedef struct UefiPayloadConfigStruct { > + UINT64 Version; > + union { > + UefiPayloadConfigV1 v1; > + struct { > + char cmdline[0]; // up to 64 KB > + } v2; > + } config; > } UefiPayloadConfig; > #pragma pack() > > -#define UEFI_PAYLOAD_CONFIG_VERSION 1 > +// magic version config is "LnxBoot1" > +#define UEFI_PAYLOAD_CONFIG_VERSION1 1 > +#define UEFI_PAYLOAD_CONFIG_VERSION2 0x31746f6f42786e4cULL > > #define LINUXBOOT_MEM_RAM 1 > #define LINUXBOOT_MEM_DEFAULT 2 > diff --git a/UefiPayloadPkg/Library/LbParseLib/LbParseLib.c > b/UefiPayloadPkg/Library/LbParseLib/LbParseLib.c > index 34bfb6a1073f..5e68091cac91 100644 > --- a/UefiPayloadPkg/Library/LbParseLib/LbParseLib.c > +++ b/UefiPayloadPkg/Library/LbParseLib/LbParseLib.c > @@ -1,13 +1,12 @@ > /** @file > - This library will parse the linuxboot table in memory and extract those > required > - information. > + This library will parse the linuxboot table in memory and extract > +those required information. > > Copyright (c) 2021, the u-root Authors. All rights reserved.
> SPDX-License-Identifier: BSD-2-Clause-Patent > > **/ > > - > #include > #include > #include > @@ -18,17 +17,42 @@ > #include > #include > #include > +#include > +#include > +//#include > +//#include > + > +#define strncmp(a, b, n) AsciiStrnCmp((a), (b), (n)) > + > +static uint64_t parse_int(const char* s, char** end) { > + UINT64 x; > + > + if (s[0] == '0' && s[1] == 'x') > + AsciiStrHexToUint64S(s, end, &x); > + else > + AsciiStrDecimalToUint64S(s, end, &x); > + > + return x; > +} > + > +static int isspace(const char c) { return c == ' ' || c == '\t' || c == > +'\n'; } > > // Retrieve UefiPayloadConfig from Linuxboot's uefiboot > -UefiPayloadConfig* GetUefiPayLoadConfig() { > - UefiPayloadConfig* config = > +const UefiPayloadConfig* GetUefiPayLoadConfig() { > + const UefiPayloadConfig* config = > (UefiPayloadConfig*)(UINTN)(PcdGet32(PcdPayloadFdMemBase) - > SIZE_64KB); > - if (config->Version != UEFI_PAYLOAD_CONFIG_VERSION) { > - DEBUG((DEBUG_ERROR, "Expect payload config version: %d, but get %d\n", > - UEFI_PAYLOAD_CONFIG_VERSION, config->Version)); > - CpuDeadLoop (); > - } > - return config; > + > + if (config->Version == UEFI_PAYLOAD_CONFIG_VERSION1 || > + config->Version == UEFI_PAYLOAD_CONFIG_VERSION2) > + return config; > + > + DEBUG((DEBUG_ERROR, > + "Expect payload config version %016lx or %016lx, but get > %016lx\n", > + UEFI_PAYLOAD_CONFIG_VERSION1, UEFI_PAYLOAD_CONFIG_VERSION2, > + config->Version)); > + CpuDeadLoop(); > + while (1) > + ; > } > > // Align the address and add memory rang to MemInfoCallback @@ -54,6 > +78,57 @@ void AddMemoryRange(IN BL_MEM_INFO_CALLBACK MemInfoCallback, IN > UINTN start, > MemInfoCallback(&MemoryMap, NULL); > } > > +const char* cmdline_next(const char* cmdline, const char** option) { > + // at the end of the string, we're done > + if (!cmdline || *cmdline == '\0') return NULL; > + > + // skip any leading whitespace > + while (isspace(*cmdline)) cmdline++; > + > + // if we've hit the end of the string, we're done if (*cmdline == > + '\0') return NULL; > + > + *option = cmdline; > + > + // find the end of this option or the string while > + (!isspace(*cmdline) && *cmdline != '\0') cmdline++; > + > + // cmdline points to the whitespace or end of string > + return cmdline; > +} > + > +int cmdline_ints(const char* option, uint64_t args[], int max) { > + // skip any leading text up to an '=' > + const char* s = option; > + while (1) { > + const char c = *s++; > + if (c == '=') break; > + > + if (c == '\0' || isspace(c)) { > + s = option; > + break; > + } > + } > + > + for (int i = 0; i < max; i++) { > + char* end; > + args[i] = parse_int(s, &end); > + > + // end of string or end of the option? > + if (*end == '\0' || isspace(*end)) return i + 1; > + > + // not separator? signal an error if we have consumed any ints, > + // otherwise return 0 saying that none were found > + if (*end != ',') return i == 0 ? 0 : -1; > + > + // skip the , and get the next value > + s = end + 1; > + } > + > + // too many values! > + return -1; > +} > + > /** > Acquire the memory information from the linuxboot table in memory. > > @@ -67,20 +142,50 @@ void AddMemoryRange(IN BL_MEM_INFO_CALLBACK > MemInfoCallback, IN UINTN start, RETURN_STATUS EFIAPI ParseMemoryInfo(IN > BL_MEM_INFO_CALLBACK MemInfoCallback, IN VOID* Params) { > - UefiPayloadConfig* config; > - int i; > + const UefiPayloadConfig* config = GetUefiPayLoadConfig(); if > + (!config) { > + DEBUG( > + (DEBUG_ERROR, "ParseMemoryInfo: Could not find UEFI Payload > config\n")); > + return RETURN_SUCCESS; > + } > + > + if (config->Version == UEFI_PAYLOAD_CONFIG_VERSION1) { > + const UefiPayloadConfigV1* config1 = &config->config.v1; > + DEBUG( > + (DEBUG_INFO, "MemoryMap #entries: %d\n", > + config1->NumMemoryMapEntries)); > + > + for (int i = 0; i < config1->NumMemoryMapEntries; i++) { > + const MemoryMapEntry* entry = &config1->MemoryMapEntries[i]; > + DEBUG((DEBUG_INFO, "Start: 0x%lx End: 0x%lx Type:%d\n", > entry->Start, > + entry->End, entry->Type)); > + AddMemoryRange(MemInfoCallback, entry->Start, entry->End, > entry->Type); > + } > + } else > > - config = GetUefiPayLoadConfig(); > + if (config->Version == UEFI_PAYLOAD_CONFIG_VERSION2) { > + const char* cmdline = config->config.v2.cmdline; > + const char* option; > + uint64_t args[3]; > > - DEBUG((DEBUG_INFO, "MemoryMap #entries: %d\n", > config->NumMemoryMapEntries)); > + // look for the mem=start,end,type > + while ((cmdline = cmdline_next(cmdline, &option))) { > + if (strncmp(option, "mem=", 4) != 0) continue; > > - MemoryMapEntry* entry = &config->MemoryMapEntries[0]; > - for (i = 0; i < config->NumMemoryMapEntries; i++) { > - DEBUG((DEBUG_INFO, "Start: 0x%lx End: 0x%lx Type:%d\n", entry->Start, > - entry->End, entry->Type)); > - AddMemoryRange(MemInfoCallback, entry->Start, entry->End, > entry->Type); > - entry++; > + if (cmdline_ints(option, args, 3) != 3) { > + DEBUG((DEBUG_ERROR, "Parse error: '%a'\n", option)); > + continue; > + } > + > + const uint64_t start = args[0]; > + const uint64_t end = args[1]; > + const uint64_t type = args[2]; > + > + DEBUG( > + (DEBUG_INFO, "Start: 0x%lx End: 0x%lx Type:%d\n", start, end, > type)); > + AddMemoryRange(MemInfoCallback, start, end, type); > + } > } > + > return RETURN_SUCCESS; > } > > @@ -96,14 +201,52 @@ ParseMemoryInfo(IN BL_MEM_INFO_CALLBACK > MemInfoCallback, IN VOID* Params) { RETURN_STATUS EFIAPI > ParseSystemTable(OUT SYSTEM_TABLE_INFO* SystemTableInfo) { > - UefiPayloadConfig* config; > + const UefiPayloadConfig* config = GetUefiPayLoadConfig(); if > + (!config) { > + DEBUG((DEBUG_ERROR, > + "ParseSystemTable: Could not find UEFI Payload config\n")); > + return RETURN_SUCCESS; > + } > > - config = GetUefiPayLoadConfig(); > - SystemTableInfo->AcpiTableBase = config->AcpiBase; > - SystemTableInfo->AcpiTableSize = config->AcpiSize; > + if (config->Version == UEFI_PAYLOAD_CONFIG_VERSION1) { > + const UefiPayloadConfigV1* config1 = &config->config.v1; > + SystemTableInfo->AcpiTableBase = config1->AcpiBase; > + SystemTableInfo->AcpiTableSize = config1->AcpiSize; > > - SystemTableInfo->SmbiosTableBase = config->SmbiosBase; > - SystemTableInfo->SmbiosTableSize = config->SmbiosSize; > + SystemTableInfo->SmbiosTableBase = config1->SmbiosBase; > + SystemTableInfo->SmbiosTableSize = config1->SmbiosSize; } else > + > + if (config->Version == UEFI_PAYLOAD_CONFIG_VERSION2) { > + const char* cmdline = config->config.v2.cmdline; > + const char* option; > + uint64_t args[2]; > + > + // look for the acpi config > + while ((cmdline = cmdline_next(cmdline, &option))) { > + if (strncmp(option, "ACPI20=", 7) == 0) { > + const int count = cmdline_ints(option, args, 2); > + if (count < 0) { > + DEBUG((DEBUG_ERROR, "Parse error: '%a'\n", option)); > + continue; > + } > + > + if (count > 0) SystemTableInfo->AcpiTableBase = args[0]; > + if (count > 1) SystemTableInfo->AcpiTableSize = args[1]; > + } > + > + if (strncmp(option, "SMBIOS=", 7) == 0) { > + const int count = cmdline_ints(option, args, 2); > + if (count < 0) { > + DEBUG((DEBUG_ERROR, "Parse error: '%a'\n", option)); > + continue; > + } > + > + if (count > 0) SystemTableInfo->SmbiosTableBase = args[0]; > + if (count > 1) SystemTableInfo->SmbiosTableSize = args[1]; > + } > + } > + } > > return RETURN_SUCCESS; > } > @@ -120,15 +263,52 @@ ParseSystemTable(OUT SYSTEM_TABLE_INFO* > SystemTableInfo) { RETURN_STATUS EFIAPI ParseSerialInfo(OUT > SERIAL_PORT_INFO* SerialPortInfo) { > - UefiPayloadConfig* config; > - config = GetUefiPayLoadConfig(); > - > - SerialPortInfo->BaseAddr = config->SerialConfig.BaseAddr; > - SerialPortInfo->RegWidth = config->SerialConfig.RegWidth; > - SerialPortInfo->Type = config->SerialConfig.Type; > - SerialPortInfo->Baud = config->SerialConfig.Baud; > - SerialPortInfo->InputHertz = config->SerialConfig.InputHertz; > - SerialPortInfo->UartPciAddr = config->SerialConfig.UartPciAddr; > + // fill in some reasonable defaults > + SerialPortInfo->BaseAddr = 0x3f8; > + SerialPortInfo->RegWidth = 1; > + SerialPortInfo->Type = 1; // uefi.SerialPortTypeIO > + SerialPortInfo->Baud = 115200; SerialPortInfo->InputHertz = 1843200; > + SerialPortInfo->UartPciAddr = 0; > + > + const UefiPayloadConfig* config = GetUefiPayLoadConfig(); if > + (!config) { > + DEBUG((DEBUG_ERROR, "ParseSerialInfo: using default config\n")); > + return RETURN_SUCCESS; > + } > + > + if (config->Version == UEFI_PAYLOAD_CONFIG_VERSION1) { > + const UefiPayloadConfigV1* config1 = &config->config.v1; > + SerialPortInfo->BaseAddr = config1->SerialConfig.BaseAddr; > + SerialPortInfo->RegWidth = config1->SerialConfig.RegWidth; > + SerialPortInfo->Type = config1->SerialConfig.Type; > + SerialPortInfo->Baud = config1->SerialConfig.Baud; > + SerialPortInfo->InputHertz = config1->SerialConfig.InputHertz; > + SerialPortInfo->UartPciAddr = config1->SerialConfig.UartPciAddr; > + } else > + > + if (config->Version == UEFI_PAYLOAD_CONFIG_VERSION2) { > + const char* cmdline = config->config.v2.cmdline; > + const char* option; > + uint64_t args[6] = {}; > + > + while ((cmdline = cmdline_next(cmdline, &option))) { > + if (strncmp(option, "serial=", 7) != 0) continue; > + > + const int count = cmdline_ints(option, args, 6); > + if (count < 0) { > + DEBUG((DEBUG_ERROR, "Parse error: %a\n", option)); > + continue; > + } > + > + if (count > 0) SerialPortInfo->Baud = args[0]; > + if (count > 1) SerialPortInfo->BaseAddr = args[1]; > + if (count > 2) SerialPortInfo->RegWidth = args[2]; > + if (count > 3) SerialPortInfo->Type = args[3]; > + if (count > 4) SerialPortInfo->InputHertz = args[4]; > + if (count > 5) SerialPortInfo->UartPciAddr = args[5]; > + } > + } > > return RETURN_SUCCESS; > } > -- > 2.32.0.402.g57bb445576-goog > > > > > > > --000000000000bb87d205c8f87a10 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Thanks for the information. I will drop this patch in Patc= h set v2 for now and work with Trammell to revise this patch to fit EDK2 st= yle.

--
Cheng-Chieh

=
On Wed, Au= g 4, 2021 at 11:00 AM Dong, Guo <g= uo.dong@intel.com> wrote:

Please run BaseTools\Scripts\PatchCheck.py to make sure it passed the check= .

Update LbParseLib.c following h= ttps://edk2-docs.gitbook.io/edk-ii-c-coding-standards-specification/. current code is more like Linux style. E.g.
+static uint64_t parse_int(const char* s, char** end) {
+=C2=A0 UINT64 x;

Removed unused comments
+//#include <string.h>
+//#include <ctype.h>


Thanks,
Guo
-----Original Message-----
From: devel@edk2.= groups.io <devel@edk2.groups.io> On Behalf Of Cheng-Chieh Huang via groups.io
Sent: Wednesday, July 21, 2021 6:23 AM
To: devel@edk2.gr= oups.io
Cc: Trammell Hudson <hudson@trmm.net>; Cheng-Chieh Huang <chengchieh@google.com>
Subject: [edk2-devel] [PATCH v1 6/6] UefiPayloadPkg: LinuxBoot: use a text = format for the configuration block.

From: Trammell Hudson <hudson@trmm.net>

This adds a text command line for the UefiPayloadPkg that uses a textual ma= gic number 'LnxBoot1' and a series of white-space separated key=3Dv= alue[,value...] pairs for the parameters.

The v1 binary configuration structure is used if it is present instead for = backwards compatability.

Currently supported text command line arguments are are:

* `serial=3Dbaud,base,width,type,hz,pci`
(only `baud` needs to be specified, the rest have reasonable
defaults)

* `mem=3Dstart,end,type`
Types are based on `/sys/firmware/memmaps/*/types`:
=C2=A0 =C2=A0 1 =3D=3D "System RAM"
=C2=A0 =C2=A0 3 =3D=3D "ACPI Tables"
=C2=A0 =C2=A0 4 =3D=3D "ACPI Non-volatile Storage"
=C2=A0 =C2=A0 5 =3D=3D "Reserved"

* `ACPI20=3Dbase` pointer to RDSP (from `/sys/firmware/efi/systab`)

* `SMBIOS=3Dbase` pointer to the SMBIOS table (also from the EFI table)

Signed-off-by: Cheng-Chieh Huang <chengchieh@google.com>
---
=C2=A0UefiPayloadPkg/Include/Linuxboot.h=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0|=C2=A0 17 +-
=C2=A0UefiPayloadPkg/Library/LbParseLib/LbParseLib.c | 252 ++++++++++++++++= +---
=C2=A02 files changed, 230 insertions(+), 39 deletions(-)

diff --git a/UefiPayloadPkg/Include/Linuxboot.h b/UefiPayloadPkg/Include/Li= nuxboot.h
index 34ca18069983..56b39b5a09ff 100644
--- a/UefiPayloadPkg/Include/Linuxboot.h
+++ b/UefiPayloadPkg/Include/Linuxboot.h
@@ -24,8 +24,7 @@ typedef struct MemoryMapEntryStruct {
=C2=A0 =C2=A0UINT32 Type;
=C2=A0} MemoryMapEntry;

-typedef struct UefiPayloadConfigStruct {
-=C2=A0 UINT64 Version;
+typedef struct {
=C2=A0 =C2=A0UINT64 AcpiBase;
=C2=A0 =C2=A0UINT64 AcpiSize;
=C2=A0 =C2=A0UINT64 SmbiosBase;
@@ -33,10 +32,22 @@ typedef struct UefiPayloadConfigStruct {
=C2=A0 =C2=A0SerialPortConfig SerialConfig;
=C2=A0 =C2=A0UINT32 NumMemoryMapEntries;
=C2=A0 =C2=A0MemoryMapEntry MemoryMapEntries[0];
+} UefiPayloadConfigV1;
+
+typedef struct UefiPayloadConfigStruct {
+=C2=A0 UINT64 Version;
+=C2=A0 union {
+=C2=A0 =C2=A0 UefiPayloadConfigV1 v1;
+=C2=A0 =C2=A0 struct {
+=C2=A0 =C2=A0 =C2=A0 char cmdline[0]; // up to 64 KB
+=C2=A0 =C2=A0 } v2;
+=C2=A0 } config;
=C2=A0} UefiPayloadConfig;
=C2=A0#pragma pack()

-#define UEFI_PAYLOAD_CONFIG_VERSION 1
+// magic version config is "LnxBoot1"
+#define UEFI_PAYLOAD_CONFIG_VERSION1 1
+#define UEFI_PAYLOAD_CONFIG_VERSION2 0x31746f6f42786e4cULL

=C2=A0#define LINUXBOOT_MEM_RAM 1
=C2=A0#define LINUXBOOT_MEM_DEFAULT 2
diff --git a/UefiPayloadPkg/Library/LbParseLib/LbParseLib.c b/UefiPayloadPk= g/Library/LbParseLib/LbParseLib.c
index 34bfb6a1073f..5e68091cac91 100644
--- a/UefiPayloadPkg/Library/LbParseLib/LbParseLib.c
+++ b/UefiPayloadPkg/Library/LbParseLib/LbParseLib.c
@@ -1,13 +1,12 @@
=C2=A0/** @file
-=C2=A0 This library will parse the linuxboot table in memory and extract t= hose required
-=C2=A0 information.
+=C2=A0 This library will parse the linuxboot table in memory and extract <= br> +those required information.

=C2=A0 =C2=A0Copyright (c) 2021, the u-root Authors. All rights reserved.&l= t;BR>
=C2=A0 =C2=A0SPDX-License-Identifier: BSD-2-Clause-Patent

=C2=A0**/

-
=C2=A0#include <IndustryStandard/Acpi.h>
=C2=A0#include <IndustryStandard/SmBios.h>
=C2=A0#include <Library/BaseLib.h>
@@ -18,17 +17,42 @@
=C2=A0#include <Library/PcdLib.h>
=C2=A0#include <Linuxboot.h>
=C2=A0#include <Uefi/UefiBaseType.h>
+#include <stdint.h>
+#include <stdlib.h>
+//#include <string.h>
+//#include <ctype.h>
+
+#define strncmp(a, b, n) AsciiStrnCmp((a), (b), (n))
+
+static uint64_t parse_int(const char* s, char** end) {
+=C2=A0 UINT64 x;
+
+=C2=A0 if (s[0] =3D=3D '0' && s[1] =3D=3D 'x')
+=C2=A0 =C2=A0 AsciiStrHexToUint64S(s, end, &x);
+=C2=A0 else
+=C2=A0 =C2=A0 AsciiStrDecimalToUint64S(s, end, &x);
+
+=C2=A0 return x;
+}
+
+static int isspace(const char c) { return c =3D=3D ' ' || c =3D=3D= '\t' || c =3D=3D
+'\n'; }

=C2=A0// Retrieve UefiPayloadConfig from Linuxboot's uefiboot
-UefiPayloadConfig* GetUefiPayLoadConfig() {
-=C2=A0 UefiPayloadConfig* config =3D
+const UefiPayloadConfig* GetUefiPayLoadConfig() {
+=C2=A0 const UefiPayloadConfig* config =3D
=C2=A0 =C2=A0 =C2=A0 =C2=A0(UefiPayloadConfig*)(UINTN)(PcdGet32(PcdPayloadF= dMemBase) - SIZE_64KB);
-=C2=A0 if (config->Version !=3D UEFI_PAYLOAD_CONFIG_VERSION) {
-=C2=A0 =C2=A0 DEBUG((DEBUG_ERROR, "Expect payload config version: %d,= but get %d\n",
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0UEFI_PAYLOAD_CONFIG_VERSION, conf= ig->Version));
-=C2=A0 =C2=A0 CpuDeadLoop ();
-=C2=A0 }
-=C2=A0 return config;
+
+=C2=A0 if (config->Version =3D=3D UEFI_PAYLOAD_CONFIG_VERSION1 ||
+=C2=A0 =C2=A0 =C2=A0 config->Version =3D=3D UEFI_PAYLOAD_CONFIG_VERSION= 2)
+=C2=A0 =C2=A0 return config;
+
+=C2=A0 DEBUG((DEBUG_ERROR,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"Expect payload config version %016= lx or %016lx, but get %016lx\n",
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0UEFI_PAYLOAD_CONFIG_VERSION1, UEFI_PAYLO= AD_CONFIG_VERSION2,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0config->Version));
+=C2=A0 CpuDeadLoop();
+=C2=A0 while (1)
+=C2=A0 =C2=A0 ;
=C2=A0}

=C2=A0// Align the address and add memory rang to MemInfoCallback @@ -54,6 = +78,57 @@ void AddMemoryRange(IN BL_MEM_INFO_CALLBACK MemInfoCallback, IN U= INTN start,
=C2=A0 =C2=A0MemInfoCallback(&MemoryMap, NULL);
=C2=A0}

+const char* cmdline_next(const char* cmdline, const char** option) {
+=C2=A0 // at the end of the string, we're done
+=C2=A0 if (!cmdline || *cmdline =3D=3D '\0') return NULL;
+
+=C2=A0 // skip any leading whitespace
+=C2=A0 while (isspace(*cmdline)) cmdline++;
+
+=C2=A0 // if we've hit the end of the string, we're done=C2=A0 if = (*cmdline =3D=3D
+ '\0') return NULL;
+
+=C2=A0 *option =3D cmdline;
+
+=C2=A0 // find the end of this option or the string=C2=A0 while
+ (!isspace(*cmdline) && *cmdline !=3D '\0') cmdline++;
+
+=C2=A0 // cmdline points to the whitespace or end of string
+=C2=A0 return cmdline;
+}
+
+int cmdline_ints(const char* option, uint64_t args[], int max) {
+=C2=A0 // skip any leading text up to an '=3D'
+=C2=A0 const char* s =3D option;
+=C2=A0 while (1) {
+=C2=A0 =C2=A0 const char c =3D *s++;
+=C2=A0 =C2=A0 if (c =3D=3D '=3D') break;
+
+=C2=A0 =C2=A0 if (c =3D=3D '\0' || isspace(c)) {
+=C2=A0 =C2=A0 =C2=A0 s =3D option;
+=C2=A0 =C2=A0 =C2=A0 break;
+=C2=A0 =C2=A0 }
+=C2=A0 }
+
+=C2=A0 for (int i =3D 0; i < max; i++) {
+=C2=A0 =C2=A0 char* end;
+=C2=A0 =C2=A0 args[i] =3D parse_int(s, &end);
+
+=C2=A0 =C2=A0 // end of string or end of the option?
+=C2=A0 =C2=A0 if (*end =3D=3D '\0' || isspace(*end)) return i + 1;=
+
+=C2=A0 =C2=A0 // not separator? signal an error if we have consumed any in= ts,
+=C2=A0 =C2=A0 // otherwise return 0 saying that none were found
+=C2=A0 =C2=A0 if (*end !=3D ',') return i =3D=3D 0 ? 0 : -1;
+
+=C2=A0 =C2=A0 // skip the , and get the next value
+=C2=A0 =C2=A0 s =3D end + 1;
+=C2=A0 }
+
+=C2=A0 // too many values!
+=C2=A0 return -1;
+}
+
=C2=A0/**
=C2=A0 =C2=A0Acquire the memory information from the linuxboot table in mem= ory.

@@ -67,20 +142,50 @@ void AddMemoryRange(IN BL_MEM_INFO_CALLBACK MemInfoCal= lback, IN UINTN start,=C2=A0 RETURN_STATUS=C2=A0 EFIAPI=C2=A0 ParseMemoryIn= fo(IN BL_MEM_INFO_CALLBACK MemInfoCallback, IN VOID* Params) {
-=C2=A0 UefiPayloadConfig* config;
-=C2=A0 int i;
+=C2=A0 const UefiPayloadConfig* config =3D GetUefiPayLoadConfig();=C2=A0 i= f
+ (!config) {
+=C2=A0 =C2=A0 DEBUG(
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 (DEBUG_ERROR, "ParseMemoryInfo: Could not= find UEFI Payload config\n"));
+=C2=A0 =C2=A0 return RETURN_SUCCESS;
+=C2=A0 }
+
+=C2=A0 if (config->Version =3D=3D UEFI_PAYLOAD_CONFIG_VERSION1) {
+=C2=A0 =C2=A0 const UefiPayloadConfigV1* config1 =3D &config->confi= g.v1;
+=C2=A0 =C2=A0 DEBUG(
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 (DEBUG_INFO, "MemoryMap #entries: %d\n&qu= ot;,
+ config1->NumMemoryMapEntries));
+
+=C2=A0 =C2=A0 for (int i =3D 0; i < config1->NumMemoryMapEntries; i+= +) {
+=C2=A0 =C2=A0 =C2=A0 const MemoryMapEntry* entry =3D &config1->Memo= ryMapEntries[i];
+=C2=A0 =C2=A0 =C2=A0 DEBUG((DEBUG_INFO, "Start: 0x%lx End: 0x%lx Type= :%d\n", entry->Start,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0entry->End, entry->T= ype));
+=C2=A0 =C2=A0 =C2=A0 AddMemoryRange(MemInfoCallback, entry->Start, entr= y->End, entry->Type);
+=C2=A0 =C2=A0 }
+=C2=A0 } else

-=C2=A0 config =3D GetUefiPayLoadConfig();
+=C2=A0 =C2=A0 =C2=A0 if (config->Version =3D=3D UEFI_PAYLOAD_CONFIG_VER= SION2) {
+=C2=A0 =C2=A0 const char* cmdline =3D config->config.v2.cmdline;
+=C2=A0 =C2=A0 const char* option;
+=C2=A0 =C2=A0 uint64_t args[3];

-=C2=A0 DEBUG((DEBUG_INFO, "MemoryMap #entries: %d\n", config->= ;NumMemoryMapEntries));
+=C2=A0 =C2=A0 // look for the mem=3Dstart,end,type
+=C2=A0 =C2=A0 while ((cmdline =3D cmdline_next(cmdline, &option))) { +=C2=A0 =C2=A0 =C2=A0 if (strncmp(option, "mem=3D", 4) !=3D 0) co= ntinue;

-=C2=A0 MemoryMapEntry* entry =3D &config->MemoryMapEntries[0];
-=C2=A0 for (i =3D 0; i < config->NumMemoryMapEntries; i++) {
-=C2=A0 =C2=A0 DEBUG((DEBUG_INFO, "Start: 0x%lx End: 0x%lx Type:%d\n&q= uot;, entry->Start,
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0entry->End, entry->Type));<= br> -=C2=A0 =C2=A0 AddMemoryRange(MemInfoCallback, entry->Start, entry->E= nd, entry->Type);
-=C2=A0 =C2=A0 entry++;
+=C2=A0 =C2=A0 =C2=A0 if (cmdline_ints(option, args, 3) !=3D 3) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 DEBUG((DEBUG_ERROR, "Parse error: '%a= '\n", option));
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 continue;
+=C2=A0 =C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 =C2=A0 const uint64_t start =3D args[0];
+=C2=A0 =C2=A0 =C2=A0 const uint64_t end =3D args[1];
+=C2=A0 =C2=A0 =C2=A0 const uint64_t type =3D args[2];
+
+=C2=A0 =C2=A0 =C2=A0 DEBUG(
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (DEBUG_INFO, "Start: 0x%lx End: 0x= %lx Type:%d\n", start, end, type));
+=C2=A0 =C2=A0 =C2=A0 AddMemoryRange(MemInfoCallback, start, end, type); +=C2=A0 =C2=A0 }
=C2=A0 =C2=A0}
+
=C2=A0 =C2=A0return RETURN_SUCCESS;
=C2=A0}

@@ -96,14 +201,52 @@ ParseMemoryInfo(IN BL_MEM_INFO_CALLBACK MemInfoCallbac= k, IN VOID* Params) {=C2=A0 RETURN_STATUS=C2=A0 EFIAPI=C2=A0 ParseSystemTab= le(OUT SYSTEM_TABLE_INFO* SystemTableInfo) {
-=C2=A0 UefiPayloadConfig* config;
+=C2=A0 const UefiPayloadConfig* config =3D GetUefiPayLoadConfig();=C2=A0 i= f
+ (!config) {
+=C2=A0 =C2=A0 DEBUG((DEBUG_ERROR,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"ParseSystemTable: Could not= find UEFI Payload config\n"));
+=C2=A0 =C2=A0 return RETURN_SUCCESS;
+=C2=A0 }

-=C2=A0 config =3D GetUefiPayLoadConfig();
-=C2=A0 SystemTableInfo->AcpiTableBase =3D config->AcpiBase;
-=C2=A0 SystemTableInfo->AcpiTableSize =3D config->AcpiSize;
+=C2=A0 if (config->Version =3D=3D UEFI_PAYLOAD_CONFIG_VERSION1) {
+=C2=A0 =C2=A0 const UefiPayloadConfigV1* config1 =3D &config->confi= g.v1;
+=C2=A0 =C2=A0 SystemTableInfo->AcpiTableBase =3D config1->AcpiBase;<= br> +=C2=A0 =C2=A0 SystemTableInfo->AcpiTableSize =3D config1->AcpiSize;<= br>
-=C2=A0 SystemTableInfo->SmbiosTableBase =3D config->SmbiosBase;
-=C2=A0 SystemTableInfo->SmbiosTableSize =3D config->SmbiosSize;
+=C2=A0 =C2=A0 SystemTableInfo->SmbiosTableBase =3D config1->SmbiosBa= se;
+=C2=A0 =C2=A0 SystemTableInfo->SmbiosTableSize =3D config1->SmbiosSi= ze;=C2=A0 } else
+
+=C2=A0 =C2=A0 =C2=A0 if (config->Version =3D=3D UEFI_PAYLOAD_CONFIG_VER= SION2) {
+=C2=A0 =C2=A0 const char* cmdline =3D config->config.v2.cmdline;
+=C2=A0 =C2=A0 const char* option;
+=C2=A0 =C2=A0 uint64_t args[2];
+
+=C2=A0 =C2=A0 // look for the acpi config
+=C2=A0 =C2=A0 while ((cmdline =3D cmdline_next(cmdline, &option))) { +=C2=A0 =C2=A0 =C2=A0 if (strncmp(option, "ACPI20=3D", 7) =3D=3D = 0) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 const int count =3D cmdline_ints(option, args,= 2);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (count < 0) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 DEBUG((DEBUG_ERROR, "Parse error: = '%a'\n", option));
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 continue;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (count > 0) SystemTableInfo->AcpiTabl= eBase =3D args[0];
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (count > 1) SystemTableInfo->AcpiTabl= eSize =3D args[1];
+=C2=A0 =C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 =C2=A0 if (strncmp(option, "SMBIOS=3D", 7) =3D=3D = 0) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 const int count =3D cmdline_ints(option, args,= 2);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (count < 0) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 DEBUG((DEBUG_ERROR, "Parse error: = '%a'\n", option));
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 continue;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (count > 0) SystemTableInfo->SmbiosTa= bleBase =3D args[0];
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (count > 1) SystemTableInfo->SmbiosTa= bleSize =3D args[1];
+=C2=A0 =C2=A0 =C2=A0 }
+=C2=A0 =C2=A0 }
+=C2=A0 }

=C2=A0 =C2=A0return RETURN_SUCCESS;
=C2=A0}
@@ -120,15 +263,52 @@ ParseSystemTable(OUT SYSTEM_TABLE_INFO* SystemTableIn= fo) {=C2=A0 RETURN_STATUS=C2=A0 EFIAPI=C2=A0 ParseSerialInfo(OUT SERIAL_POR= T_INFO* SerialPortInfo) {
-=C2=A0 UefiPayloadConfig* config;
-=C2=A0 config =3D GetUefiPayLoadConfig();
-
-=C2=A0 SerialPortInfo->BaseAddr =3D config->SerialConfig.BaseAddr; -=C2=A0 SerialPortInfo->RegWidth =3D config->SerialConfig.RegWidth; -=C2=A0 SerialPortInfo->Type =3D config->SerialConfig.Type;
-=C2=A0 SerialPortInfo->Baud =3D config->SerialConfig.Baud;
-=C2=A0 SerialPortInfo->InputHertz =3D config->SerialConfig.InputHert= z;
-=C2=A0 SerialPortInfo->UartPciAddr =3D config->SerialConfig.UartPciA= ddr;
+=C2=A0 // fill in some reasonable defaults
+=C2=A0 SerialPortInfo->BaseAddr =3D 0x3f8;
+=C2=A0 SerialPortInfo->RegWidth =3D 1;
+=C2=A0 SerialPortInfo->Type =3D 1;=C2=A0 // uefi.SerialPortTypeIO=C2=A0=
+ SerialPortInfo->Baud =3D 115200;=C2=A0 SerialPortInfo->InputHertz = =3D 1843200;=C2=A0
+ SerialPortInfo->UartPciAddr =3D 0;
+
+=C2=A0 const UefiPayloadConfig* config =3D GetUefiPayLoadConfig();=C2=A0 i= f
+ (!config) {
+=C2=A0 =C2=A0 DEBUG((DEBUG_ERROR, "ParseSerialInfo: using default con= fig\n"));
+=C2=A0 =C2=A0 return RETURN_SUCCESS;
+=C2=A0 }
+
+=C2=A0 if (config->Version =3D=3D UEFI_PAYLOAD_CONFIG_VERSION1) {
+=C2=A0 =C2=A0 const UefiPayloadConfigV1* config1 =3D &config->confi= g.v1;
+=C2=A0 =C2=A0 SerialPortInfo->BaseAddr =3D config1->SerialConfig.Bas= eAddr;
+=C2=A0 =C2=A0 SerialPortInfo->RegWidth =3D config1->SerialConfig.Reg= Width;
+=C2=A0 =C2=A0 SerialPortInfo->Type =3D config1->SerialConfig.Type; +=C2=A0 =C2=A0 SerialPortInfo->Baud =3D config1->SerialConfig.Baud; +=C2=A0 =C2=A0 SerialPortInfo->InputHertz =3D config1->SerialConfig.I= nputHertz;
+=C2=A0 =C2=A0 SerialPortInfo->UartPciAddr =3D config1->SerialConfig.= UartPciAddr;
+=C2=A0 } else
+
+=C2=A0 =C2=A0 =C2=A0 if (config->Version =3D=3D UEFI_PAYLOAD_CONFIG_VER= SION2) {
+=C2=A0 =C2=A0 const char* cmdline =3D config->config.v2.cmdline;
+=C2=A0 =C2=A0 const char* option;
+=C2=A0 =C2=A0 uint64_t args[6] =3D {};
+
+=C2=A0 =C2=A0 while ((cmdline =3D cmdline_next(cmdline, &option))) { +=C2=A0 =C2=A0 =C2=A0 if (strncmp(option, "serial=3D", 7) !=3D 0)= continue;
+
+=C2=A0 =C2=A0 =C2=A0 const int count =3D cmdline_ints(option, args, 6); +=C2=A0 =C2=A0 =C2=A0 if (count < 0) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 DEBUG((DEBUG_ERROR, "Parse error: %a\n&qu= ot;, option));
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 continue;
+=C2=A0 =C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 =C2=A0 if (count > 0) SerialPortInfo->Baud =3D args[0]= ;
+=C2=A0 =C2=A0 =C2=A0 if (count > 1) SerialPortInfo->BaseAddr =3D arg= s[1];
+=C2=A0 =C2=A0 =C2=A0 if (count > 2) SerialPortInfo->RegWidth =3D arg= s[2];
+=C2=A0 =C2=A0 =C2=A0 if (count > 3) SerialPortInfo->Type =3D args[3]= ;
+=C2=A0 =C2=A0 =C2=A0 if (count > 4) SerialPortInfo->InputHertz =3D a= rgs[4];
+=C2=A0 =C2=A0 =C2=A0 if (count > 5) SerialPortInfo->UartPciAddr =3D = args[5];
+=C2=A0 =C2=A0 }
+=C2=A0 }

=C2=A0 =C2=A0return RETURN_SUCCESS;
=C2=A0}
--
2.32.0.402.g57bb445576-goog






--000000000000bb87d205c8f87a10--