From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by mx.groups.io with SMTP id smtpd.web11.19507.1661183371876831805 for ; Mon, 22 Aug 2022 08:49:32 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=YTorADNs; spf=pass (domain: intel.com, ip: 192.55.52.120, mailfrom: guo.dong@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1661183371; x=1692719371; h=from:to:cc:subject:date:message-id:references: in-reply-to:content-transfer-encoding:mime-version; bh=AYUIUQmMj4UG4n2TtQefShlTwYEmUO5qjGYPTBffuss=; b=YTorADNspvd1+mgv+kJA1aqr7nei8InyQuDQ5VjHgbsuKnq5kB0iZZxM 2vDV7s55z/lbg3pVA19FSV6uDDo3knm/cflO1yVaXvuviE3E0Y4Zgyxjo N2M7ouzJvcYQ2uXP9ch3d0Z6W7ivggsALFnOd6LAVkQWcBtFz3Z2xni8X fJTDLmP+XexSnEfRkK+ZB6Yevo86tXg67ZVv2MxVLCFYCIZNiDVAeGgkS ksufwq3xyyysDCtAczwJ5UjXxiwKCxrGQseEUTtnHnx1MMzEYpauIThQk vkyZUPe371p40xoszvw/WI/2lN/2bC8jnwZLkwlJboUUqNJl/0eNxaPj3 g==; X-IronPort-AV: E=McAfee;i="6500,9779,10447"; a="292190178" X-IronPort-AV: E=Sophos;i="5.93,255,1654585200"; d="scan'208";a="292190178" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Aug 2022 08:49:17 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.93,255,1654585200"; d="scan'208";a="677262046" Received: from orsmsx603.amr.corp.intel.com ([10.22.229.16]) by fmsmga004.fm.intel.com with ESMTP; 22 Aug 2022 08:49:17 -0700 Received: from orsmsx608.amr.corp.intel.com (10.22.229.21) by ORSMSX603.amr.corp.intel.com (10.22.229.16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31; Mon, 22 Aug 2022 08:49:17 -0700 Received: from orsmsx609.amr.corp.intel.com (10.22.229.22) by ORSMSX608.amr.corp.intel.com (10.22.229.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31; Mon, 22 Aug 2022 08:49:16 -0700 Received: from ORSEDG602.ED.cps.intel.com (10.7.248.7) by orsmsx609.amr.corp.intel.com (10.22.229.22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31 via Frontend Transport; Mon, 22 Aug 2022 08:49:16 -0700 Received: from NAM11-DM6-obe.outbound.protection.outlook.com (104.47.57.169) by edgegateway.intel.com (134.134.137.103) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2375.31; Mon, 22 Aug 2022 08:49:16 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=R0BdzqjS2MdZqMQ3kgjc491jccyuaMAiRa2v4RcukNrnOUnHrJGC1MuGae/PNK4m+KFvyRdczIt83+mqRhbwFeXXDgZ1jyxbBmBGiOUDqb8EUs3J7waWxI1ADtl2s/PsnQiKml/tTo/eoRNZMflbRhvMWODcgIAGIVmw3nnRAavST4cNTErGyZgEmerAmUknVE7N32RkRjETQoiNfR/ysOvwlJj7HtxKntRF4cbDgNPwzs8MyT70bjixDfMI6YEV9O+xIGuF4qTYWoxGzfLHu/zUEbc0t4dnkprHu2jLmc0Ff9N0UngCY7Q0r7FXxW7gyVIWLtqFYGM1Ko4avgrpyQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=ZhtsdQC7VpU+1pQK0hNp5rDDO/MasEJAzk4hqWGxkCA=; b=URpdOzK0SRjg2gZ8jM5K0HnWWMSq8Q952fgrxRYRfXeoshHaV1HNZrjm4NnK3hyJCFY8zsyEpw5uUpYf1jhoNaOe85TIzVdI4Gs0OnUiBDzxgnuM2sBf4BY+kU9ZCN9pEf7yS5gUga9xyZ+oZGR3+pS2f8PQL6XzTKppsWkk/hAAkIuFzMuu1FULyGqcRngub4iL8U5g7pMmbbeseIszO7zzsGGB6UEUu5P6pBJeUjEha+C0KOJwYH9uyHI4tHdGcCdgpCebLr5Q/3WfnTQpw4SHuI42XgAgcg9/RbNbLt/XfOJDWunCMEBsDrhAvs4VSae993j8Ym9j6hq1Piwumw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none Received: from CY5PR11MB6260.namprd11.prod.outlook.com (2603:10b6:930:23::16) by BL1PR11MB5350.namprd11.prod.outlook.com (2603:10b6:208:31c::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5546.18; Mon, 22 Aug 2022 15:49:13 +0000 Received: from CY5PR11MB6260.namprd11.prod.outlook.com ([fe80::a881:6cab:38a6:d6a5]) by CY5PR11MB6260.namprd11.prod.outlook.com ([fe80::a881:6cab:38a6:d6a5%8]) with mapi id 15.20.5546.022; Mon, 22 Aug 2022 15:49:13 +0000 From: "Guo Dong" To: "Sravanthi, K KavyaX" , "devel@edk2.groups.io" CC: "Ni, Ray" , "Rhodes, Sean" , "Guo, Gua" Subject: Re: [PATCH v4 1/2] UefiPayloadPkg: Implement a new SerialPortLib instance Thread-Topic: [PATCH v4 1/2] UefiPayloadPkg: Implement a new SerialPortLib instance Thread-Index: AQHYoLnZL/E37omt70apbAKVjQf2ia27N+bA Date: Mon, 22 Aug 2022 15:49:13 +0000 Message-ID: References: <20220726063430.714-1-k.kavyax.sravanthi@intel.com> In-Reply-To: <20220726063430.714-1-k.kavyax.sravanthi@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-product: dlpe-windows dlp-reaction: no-action dlp-version: 11.6.500.17 authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: b9c27861-3933-44bc-baaf-08da8455dc8b x-ms-traffictypediagnostic: BL1PR11MB5350:EE_ x-ld-processed: 46c98d88-e344-4ed4-8496-4ed7712e255d,ExtAddr x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: /OYqvTB5CWMIJS1TAs9v+LhK8rgHbw49WknaxRDZQ2T+Z17NRoNQ+kJHMG6LxsvyoaVnr9pWy56bK5K41N2LzFTzuuBi2i4wBvbwg/O61ffP1xg0TJsezVM6pMcOYlRQ3h9BdBZMYFGOxGcvnYMDFQFRffvPm8Rx/AJHshowp2H/G/dxdAJyH5YLBV9F1SiigSE3JPxm9BrxPOYa/K3GXAbxhRrjD/wuDQ+lfA89F3Ghyb2nBumHE6/zz5HnOR7ePEECNqWiYQbAvqQjoz9TO1MYFwNt9AsSst1X/ylBHg6XxNMtljHmDiwn69puf12Euwwr1ez2Tzq0rRCoMM0YUTFdgGlyZI3UMXQD7+ECnpzayjalx13Tj99rOF9Zusp4O9rytW+SnONVq5HZBrXlZ4gI3CE3lmPo01LXhJYhNEcxdmX4URoDOdSnIDgHETwIll2CbqIBUxuEJfxv6/6FaHsVmQfH/UuBNz9nlQqi4WAnqG+itIC2G24qWlsw+2ptm5v5LWKcXb3miFTHcdwHw7Sg3H3M5hzduladWzTJv+XCml+U/2tI19wfe5AnuHKnQFzazpVx38dEotjGinJEMwPvFXPNGPeA0LfnMzhCygANM4G81hXvBOsjh7rAyyHaQzsZMbCxSfp3XPCeHZV7BoCOwH2QwD2WEs0CMfNmzIonxjmvMZfO/Ab2DmCU5HYx9iW5z/UU6M2e/7/tzZnvuzva9dbRI8HYO/Z32O+RPaPg8H+5oehnH5c4cdYsHEquFe/7rqg4M8/WTTAbvPfuPA== x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CY5PR11MB6260.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230016)(39860400002)(396003)(346002)(136003)(376002)(366004)(6506007)(7696005)(478600001)(71200400001)(41300700001)(83380400001)(186003)(9686003)(8936002)(107886003)(53546011)(2906002)(5660300002)(30864003)(55016003)(52536014)(316002)(54906003)(110136005)(8676002)(66446008)(66556008)(4326008)(64756008)(76116006)(66476007)(66946007)(38100700002)(122000001)(86362001)(38070700005)(82960400001)(33656002)(579004)(559001);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?vFPgdT7t2nLw4pdACnvE9JZ4a5uvK2sjTVeW7XV5JH0uU6k9SGM7zJdolfmR?= =?us-ascii?Q?XwwKQ4HuI1bvFzzwIqpeHCki/bekaQw/WjB0cDfW4yK9pyjNNQaG17ehAaRg?= =?us-ascii?Q?HIbK1Qvlaxh4OuU8X99WjX4tuwtN4satcTy6jClm7XB70Z+idwAdtxf9uAla?= =?us-ascii?Q?kDRNVszTm9GAXn2CRC64XSAC4VQmX53MQz47wAE1wALQ5lrK3eII9+nzey58?= =?us-ascii?Q?zmOmHmiUCCJT6mpnbtAASO3J9qT1a4aQDlaT7XLRCLQ186q9TgP2WNzT0raO?= =?us-ascii?Q?AYuahv5MbfVqgUqSwCu2mXFuhrJgqOEKK/yrhS0fithzyxl7pzm+Tl63Gxta?= =?us-ascii?Q?LpYM/d6FZ3IbCRMAbe6x6DFT/PCaC8Ev9Nhk9vuqvjVx+Fihl+xq6hOrf1IQ?= =?us-ascii?Q?Mcd6ugDCkw4ZpNJaXdl1/fnnMggIOZcyS5K3viN9gmpBnoKopnwcVwuTJPIQ?= =?us-ascii?Q?0inSAtxfmWuL7fReCoadxAr9ozUGpe237tjWzQKg/elzwIwFN8osPoF/zW+q?= =?us-ascii?Q?NLaKuPmVfrssCN/cD1xA/4s7J0PNpZoz46d6AzSLCFBvtKm+VSGm1jRJE3Aj?= =?us-ascii?Q?96Tl9uidT//VsJ6XgPknCvskaBgF+CS4l+5vChGLR801G1HaQmsJhRstviDP?= =?us-ascii?Q?yaYu/uZVKyBGN5x1WEnmS2MzKbIKPRqtAsEGXWJGNgtKpokEJmSMgBVqcz0g?= =?us-ascii?Q?ev6kvuSVZaA06Huw8syxEgdY+LlGnLNQ1oh/w2Zuoroigx0aFHnKZd7fdpHi?= =?us-ascii?Q?ifhRbreD0onlRpVc007zLx2XXtmrdGr0WqGqdsdLPX7MyPsJEbIQe6TqED86?= =?us-ascii?Q?fQKPTGP5fjhEAalXSAfrGO0Dsmy7I3/+AAsN1uBxtJY0XnlJOci4r05qrye7?= =?us-ascii?Q?aYpSZvXP94AaO8utJXeEI4j+Da/f4oizcIkICMe4SglC1HHIRf3i3TflEtwn?= =?us-ascii?Q?5nz5HDxLWYJLIHlEi2q7bVZd4Lq1YaJkmnSpeg11RIylV9T0oWvwvEQyPEXU?= =?us-ascii?Q?6eJc5hEz7Eyb5Ue9kOozUzDtPzsjUKdNjtk75xPVr7DRgDa1rbHaKsEjF584?= =?us-ascii?Q?pSdJQY2Xjz8kG6Rl78VkmqbRZLNq0lueKrzVLHQNgf4L1BBRuLQQy+sk5qaK?= =?us-ascii?Q?E67jNQlJgp9KCx8B90ZeAoLNfIyrRvchTJnpcYUlbGjDj7xsmxL4eaAKgdSp?= =?us-ascii?Q?pjO8mbKFpmeNSFpE5Bk62wpiRMjCKltKGBpIrHD2oqIGzEwj0AdRtp+7lwlZ?= =?us-ascii?Q?4tLBSRtuYvJUhlO2Ki03tmGCF3xil0ixiSY3LJWtz20J/4g5rr/3SqexGnIL?= =?us-ascii?Q?4mf5PPU9WJ5+JalENcAFLVLllGR+4L2BoRCx25/kvsmd5u8GcrbV+HknaPCr?= =?us-ascii?Q?m2rZqQlPIixROVDXDRcwHBezBmgRQS4p/oTcFiWza+TjdltHqFrt7UXzZdGm?= =?us-ascii?Q?MdCSjlM2HPpQ6KsldGmr7991LurvyQ8h0jvJm6Hp9hEkwGOoz48g3MZiH2E+?= =?us-ascii?Q?gnz7LIf+8NZmfv9iRn0+OiwFrK8PRh5jjnW5nyC9XlG3i4QIENNaeygQbOfQ?= =?us-ascii?Q?PxUhs+j5oeNeXRcJbleJ7ibMDirGE200bTxwu97CijDZ2T0Ad+WK+9ajKCCa?= =?us-ascii?Q?Ga2Rmx0cPDzJJdh8s5S0PZLJElI4Fztkja+0w5xM9c1o?= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: CY5PR11MB6260.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: b9c27861-3933-44bc-baaf-08da8455dc8b X-MS-Exchange-CrossTenant-originalarrivaltime: 22 Aug 2022 15:49:13.3422 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: NuBb7+3wqskOUt23N1PMqIzlfMQff2npZa6V+66e/5UNxwMuHSaiJSHobj4C2gK538a8UmgnBGUTPkETMqT4PQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: BL1PR11MB5350 Return-Path: guo.dong@intel.com X-OriginatorOrg: intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable In SerialPortInitialize(), these code could be removed. + Count =3D 0; + + GuidHob =3D GetFirstGuidHob (&gUniversalPayloadSerialPortInfoGuid); + while (GuidHob !=3D NULL) { + Count++; + GuidHob =3D GET_NEXT_HOB (GuidHob); + GuidHob =3D GetNextGuidHob (&gUniversalPayloadSerialPortInfoGuid, Guid= Hob); + } + + mUartCount =3D Count; + + Index =3D 0; And change Index to mUartCount in below code. Since multiple serial port support and SerialRegisterBase check, one serial= port failure should not impact others. So SerialRegisterBase check failure should continue checking other serial p= ort. And move this check before setting mUartInfo. + GuidHob =3D GetFirstGuidHob (&gUniversalPayloadSerialPortInfoGuid); + while (GuidHob !=3D NULL) { + SerialPortInfo =3D (UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO *)GET_GUID_HOB_= DATA (GuidHob); + SerialRegisterBase =3D SerialPortInfo->RegisterBase; + MmioEnable =3D SerialPortInfo->UseMmio; + BaudRate =3D SerialPortInfo->BaudRate; + RegisterStride =3D SerialPortInfo->RegisterStride; + + mUartInfo[Index].BaseAddress =3D SerialRegisterBase; + mUartInfo[Index].UseMmio =3D MmioEnable; + mUartInfo[Index].BaudRate =3D BaudRate; + mUartInfo[Index].RegisterStride =3D RegisterStride; + Index++; + + if (SerialRegisterBase =3D=3D 0) { + return RETURN_DEVICE_ERROR; + } Thanks, Guo -----Original Message----- From: Sravanthi, K KavyaX =20 Sent: Monday, July 25, 2022 11:34 PM To: devel@edk2.groups.io Cc: Sravanthi, K KavyaX ; Dong, Guo ; Ni, Ray ; Rhodes, Sean ; Guo, Gua Subject: [PATCH v4 1/2] UefiPayloadPkg: Implement a new SerialPortLib insta= nce Add new Serial port library instance that consumes the HOB defined in MdeMo= dulePkg/Include/UniversalPayload/SerialPortInfo.h to support multiple UART'= s. Cc: Guo Dong Cc: Ray Ni Cc: Sean Rhodes Cc: Gua Guo Signed-off-by: Kavya --- UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibHob.c | 808= ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibHob.inf | 39= +++++++++++++++++++++++++++++++++++++++ 2 files changed, 847 insertions(+) diff --git a/UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibH= ob.c b/UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibHob.c new file mode 100644 index 0000000000..140ecf5f4d --- /dev/null +++ b/UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibHob.c @@ -0,0 +1,808 @@ +/** @file + UART Serial Port library functions. + + Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +// 16550 UART register offsets and bitfields // +#define R_UART_RXBUF 0 // LCR_DLAB =3D 0 +#define R_UART_TXBUF 0 // LCR_DLAB =3D 0 +#define R_UART_BAUD_LOW 0 // LCR_DLAB =3D 1 +#define R_UART_BAUD_HIGH 1 // LCR_DLAB =3D 1 +#define R_UART_IER 1 // LCR_DLAB =3D 0 +#define R_UART_FCR 2 +#define B_UART_FCR_FIFOE BIT0 +#define B_UART_FCR_FIFO64 BIT5 +#define R_UART_LCR 3 +#define B_UART_LCR_DLAB BIT7 +#define R_UART_MCR 4 +#define B_UART_MCR_DTRC BIT0 +#define B_UART_MCR_RTS BIT1 +#define R_UART_LSR 5 +#define B_UART_LSR_RXRDY BIT0 +#define B_UART_LSR_TXRDY BIT5 +#define B_UART_LSR_TEMT BIT6 +#define R_UART_MSR 6 +#define B_UART_MSR_CTS BIT4 +#define B_UART_MSR_DSR BIT5 +#define B_UART_MSR_RI BIT6 +#define B_UART_MSR_DCD BIT7 + +#define MAX_SIZE 16 + +typedef struct { + UINTN BaseAddress; + BOOLEAN UseMmio; + UINT32 BaudRate; + UINT8 RegisterStride; +} UART_INFO; + +UART_INFO mUartInfo[MAX_SIZE]; +UINT8 mUartCount =3D 0; + +/** + Reads an 8-bit register. If UseMmio is TRUE, then the value is read=20 +from + MMIO space. If UseMmio is FALSE, then the value is read from I/O=20 +space. The + parameter Offset is added to the base address of the register. + + @param Base The base address register of UART device. + @param Offset The offset of the register to read. + @param UseMmio Check if value has to be read from MMIO space o= r IO space. + @param RegisterStride Number of bytes between registers in serial dev= ice. + + @return The value read from the register. + +**/ +UINT8 +SerialPortReadRegister ( + UINTN Base, + UINTN Offset, + BOOLEAN UseMmio, + UINT8 RegisterStride + ) +{ + if (UseMmio) { + return MmioRead8 (Base + Offset * RegisterStride); + } else { + return IoRead8 (Base + Offset * RegisterStride); + } +} + +/** + Writes an 8-bit register.. If UseMmio is TRUE, then the value is=20 +written to + MMIO space. If UseMmio is FALSE, then the value is written to I/O=20 +space. The + parameter Offset is added to the base address of the registers. + + @param Base The base address register of UART device. + @param Offset The offset of the register to write. + @param Value Value to be written. + @param UseMmio Check if value has to be written to MMIO space = or IO space. + @param RegisterStride Number of bytes between registers in serial dev= ice. + + @return The value written to the register. + +**/ +UINT8 +SerialPortWriteRegister ( + UINTN Base, + UINTN Offset, + UINT8 Value, + BOOLEAN UseMmio, + UINT8 RegisterStride + ) +{ + if (UseMmio) { + return MmioWrite8 (Base + Offset * RegisterStride, Value); + } else { + return IoWrite8 (Base + Offset * RegisterStride, Value); + } +} + +/** + Initialize the serial device hardware. + + If no initialization is required, then return RETURN_SUCCESS. + If the serial device was successfully initialized, then return RETURN_SU= CCESS. + 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 + ) +{ + UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO *SerialPortInfo; + EFI_HOB_GUID_TYPE *GuidHob; + UINTN SerialRegisterBase; + UINT8 RegisterStride; + UINT32 Divisor; + UINT32 CurrentDivisor; + UINT32 BaudRate; + BOOLEAN Initialized; + BOOLEAN MmioEnable; + UINT8 Index; + UINT8 Count; + + Count =3D 0; + + GuidHob =3D GetFirstGuidHob (&gUniversalPayloadSerialPortInfoGuid); + while (GuidHob !=3D NULL) { + Count++; + GuidHob =3D GET_NEXT_HOB (GuidHob); + GuidHob =3D GetNextGuidHob (&gUniversalPayloadSerialPortInfoGuid,=20 + GuidHob); } + + mUartCount =3D Count; + + Index =3D 0; + GuidHob =3D GetFirstGuidHob (&gUniversalPayloadSerialPortInfoGuid); + while (GuidHob !=3D NULL) { + SerialPortInfo =3D (UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO *)GET_GUID_HOB_= DATA (GuidHob); + SerialRegisterBase =3D SerialPortInfo->RegisterBase; + MmioEnable =3D SerialPortInfo->UseMmio; + BaudRate =3D SerialPortInfo->BaudRate; + RegisterStride =3D SerialPortInfo->RegisterStride; + + mUartInfo[Index].BaseAddress =3D SerialRegisterBase; + mUartInfo[Index].UseMmio =3D MmioEnable; + mUartInfo[Index].BaudRate =3D BaudRate; + mUartInfo[Index].RegisterStride =3D RegisterStride; + Index++; + + if (SerialRegisterBase =3D=3D 0) { + return RETURN_DEVICE_ERROR; + } + + Divisor =3D PcdGet32 (PcdSerialClockRate) / (BaudRate * 16); + if ((PcdGet32 (PcdSerialClockRate) % (BaudRate * 16)) >=3D BaudRate * = 8) { + Divisor++; + } + + // + // See if the serial port is already initialized + // + Initialized =3D TRUE; + if ((SerialPortReadRegister (SerialRegisterBase, R_UART_LCR, MmioEnabl= e, RegisterStride) & 0x3F) !=3D (PcdGet8 (PcdSerialLineControl) & 0x3F)) { + Initialized =3D FALSE; + } + + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8)(Seria= lPortReadRegister (SerialRegisterBase, R_UART_LCR, MmioEnable, RegisterStri= de) | B_UART_LCR_DLAB), MmioEnable, RegisterStride); + CurrentDivisor =3D SerialPortReadRegister (SerialRegisterBase, R_UAR= T_BAUD_HIGH, MmioEnable, RegisterStride) << 8; + CurrentDivisor |=3D (UINT32)SerialPortReadRegister (SerialRegisterBase= , R_UART_BAUD_LOW, MmioEnable, RegisterStride); + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8)(Seria= lPortReadRegister (SerialRegisterBase, R_UART_LCR, MmioEnable, RegisterStri= de) & ~B_UART_LCR_DLAB), MmioEnable, RegisterStride); + if (CurrentDivisor !=3D Divisor) { + Initialized =3D FALSE; + } + + if (Initialized) { + GuidHob =3D GET_NEXT_HOB (GuidHob); + GuidHob =3D GetNextGuidHob (&gUniversalPayloadSerialPortInfoGuid, Gu= idHob); + continue; + } + + // + // Configure baud rate + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, B_UART_LCR_DL= AB, MmioEnable, RegisterStride); + SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_HIGH, (UINT8)= (Divisor >> 8), MmioEnable, RegisterStride); + SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_LOW,=20 + (UINT8)(Divisor & 0xff), MmioEnable, RegisterStride); + + // + // Clear DLAB and configure Data Bits, Parity, and Stop Bits. + // Strip reserved bits from PcdSerialLineControl + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR,=20 + (UINT8)(PcdGet8 (PcdSerialLineControl) & 0x3F), MmioEnable,=20 + RegisterStride); + + // + // Enable and reset FIFOs + // Strip reserved bits from PcdSerialFifoControl + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, 0x00, MmioEna= ble, RegisterStride); + SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR,=20 + (UINT8)(PcdGet8 (PcdSerialFifoControl) & (B_UART_FCR_FIFOE |=20 + B_UART_FCR_FIFO64)), MmioEnable, RegisterStride); + + // + // Set FIFO Polled Mode by clearing IER after setting FCR + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_IER, 0x00,=20 + MmioEnable, RegisterStride); + + // + // Put Modem Control Register(MCR) into its reset state of 0x00. + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, 0x00,=20 + MmioEnable, RegisterStride); + + GuidHob =3D GET_NEXT_HOB (GuidHob); + GuidHob =3D GetNextGuidHob (&gUniversalPayloadSerialPortInfoGuid,=20 + GuidHob); } + + 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 return 0. + + 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 devic= e. + If this value is less than NumberOfBytes, then = the write operation failed. + +**/ +UINTN +EFIAPI +SerialPortWrite ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + UINTN BaseAddress; + BOOLEAN UseMmio; + UINTN BytesLeft; + UINTN Index; + UINTN FifoSize; + UINT8 *DataBuffer; + UINT8 Count; + UINT8 Stride; + + if (Buffer =3D=3D NULL || NumberOfBytes =3D=3D 0 || mUartCount =3D=3D 0)= { + return 0; + } + + // + // Compute the maximum size of the Tx FIFO // FifoSize =3D 1; if=20 + ((PcdGet8 (PcdSerialFifoControl) & B_UART_FCR_FIFOE) !=3D 0) { + if ((PcdGet8 (PcdSerialFifoControl) & B_UART_FCR_FIFO64) =3D=3D 0) { + FifoSize =3D 16; + } else { + FifoSize =3D PcdGet32 (PcdSerialExtendedTxFifoSize); + } + } + + Count =3D 0; + while (Count < mUartCount) { + BaseAddress =3D mUartInfo[Count].BaseAddress; + UseMmio =3D mUartInfo[Count].UseMmio; + Stride =3D mUartInfo[Count].RegisterStride; + + DataBuffer =3D Buffer; + BytesLeft =3D NumberOfBytes; + + while (BytesLeft !=3D 0) { + // + // Fill the entire Tx FIFO + // + for (Index =3D 0; Index < FifoSize && BytesLeft !=3D 0; Index++, Byt= esLeft--, DataBuffer++) { + // + // Write byte to the transmit buffer. + // + SerialPortWriteRegister (BaseAddress, R_UART_TXBUF, *DataBuffer, U= seMmio, Stride); + } + MicroSecondDelay (20); + } + Count++; + } + + return NumberOfBytes; +} + +/** + Reads data from a serial device into a buffer. + + @param Buffer Pointer to the data buffer to store the data re= ad from the serial device. + @param NumberOfBytes Number of bytes to read from the serial device. + + @retval 0 NumberOfBytes is 0. + @retval >0 The number of bytes read from the serial device= . + If this value is less than NumberOfBytes, then = the read operation failed. + +**/ +UINTN +EFIAPI +SerialPortRead ( + OUT UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + UINTN BaseAddress; + BOOLEAN UseMmio; + UINT8 *DataBuffer; + UINTN BytesLeft; + UINTN Result; + UINT8 Mcr; + UINT8 Count; + UINT8 Stride; + + if (Buffer =3D=3D NULL) { + return 0; + } + + Count =3D 0; + while (Count < mUartCount) { + BaseAddress =3D mUartInfo[Count].BaseAddress; + UseMmio =3D mUartInfo[Count].UseMmio; + Stride =3D mUartInfo[Count].RegisterStride; + + DataBuffer =3D Buffer; + BytesLeft =3D NumberOfBytes; + + if (BaseAddress =3D=3D 0) { + return 0; + } + + Mcr =3D (UINT8)(SerialPortReadRegister (BaseAddress, R_UART_MCR,=20 + UseMmio, Stride) & ~B_UART_MCR_RTS); + + for (Result =3D 0; BytesLeft-- !=3D 0; Result++, DataBuffer++) { + // + // Wait for the serial port to have some data. + // + while ((SerialPortReadRegister (BaseAddress, R_UART_LSR, UseMmio, St= ride) & B_UART_LSR_RXRDY) =3D=3D 0) { + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { + // + // Set RTS to let the peer send some data + // + SerialPortWriteRegister (BaseAddress, R_UART_MCR, (UINT8)(Mcr | = B_UART_MCR_RTS), UseMmio, Stride); + } + } + + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { + // + // Clear RTS to prevent peer from sending data + // + SerialPortWriteRegister (BaseAddress, R_UART_MCR, Mcr, UseMmio, St= ride); + } + + // + // Read byte from the receive buffer. + // + *DataBuffer =3D SerialPortReadRegister (BaseAddress, R_UART_RXBUF, U= seMmio, Stride); + } + Count++; + } + + return Result; +} + +/** + Polls a serial device to see if there is any data waiting to be read. + + Polls a serial device to see if there is any data waiting to be read. + If there is data waiting to be read from the serial device, then TRUE is= returned. + If there is no data waiting to be read from the serial device, then FALS= E is returned. + + @retval TRUE Data is waiting to be read from the serial devi= ce. + @retval FALSE There is no data waiting to be read from the se= rial device. + +**/ +BOOLEAN +EFIAPI +SerialPortPoll ( + VOID + ) +{ + UINTN BaseAddress; + BOOLEAN UseMmio; + UINT8 Stride; + UINT8 Count; + + Count =3D 0; + while (Count < mUartCount) { + BaseAddress =3D mUartInfo[Count].BaseAddress; + UseMmio =3D mUartInfo[Count].UseMmio; + Stride =3D mUartInfo[Count].RegisterStride; + + if (BaseAddress =3D=3D 0) { + return FALSE; + } + + // + // Read the serial port status + // + if ((SerialPortReadRegister (BaseAddress, R_UART_LSR, UseMmio, Stride)= & B_UART_LSR_RXRDY) !=3D 0) { + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { + // + // Clear RTS to prevent peer from sending data + // + SerialPortWriteRegister (BaseAddress, R_UART_MCR, (UINT8)(SerialPo= rtReadRegister (BaseAddress, R_UART_MCR, UseMmio, Stride) & ~B_UART_MCR_RTS= ), UseMmio, Stride); + } + return TRUE; + } + + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { + // + // Set RTS to let the peer send some data + // + SerialPortWriteRegister (BaseAddress, R_UART_MCR, (UINT8)(SerialPort= ReadRegister (BaseAddress, R_UART_MCR, UseMmio, Stride) | B_UART_MCR_RTS), = UseMmio, Stride); + } + Count++; + } + 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 seria= l device. + @retval RETURN_UNSUPPORTED The serial device does not support this op= eration. + @retval RETURN_DEVICE_ERROR The serial device is not functioning corre= ctly. + +**/ +RETURN_STATUS +EFIAPI +SerialPortSetControl ( + IN UINT32 Control + ) +{ + UINTN BaseAddress; + BOOLEAN UseMmio; + UINT8 Mcr; + UINT8 Count; + UINT8 Stride; + + Count =3D 0; + while (Count < mUartCount) { + BaseAddress =3D mUartInfo[Count].BaseAddress; + UseMmio =3D mUartInfo[Count].UseMmio; + Stride =3D mUartInfo[Count].RegisterStride; + + if (BaseAddress =3D=3D 0) { + return RETURN_UNSUPPORTED; + } + + // + // First determine the parameter is invalid. + // + if ((Control & (~(EFI_SERIAL_REQUEST_TO_SEND | EFI_SERIAL_DATA_TERMINA= L_READY | + EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE))) !=3D 0) + { + return RETURN_UNSUPPORTED; + } + + // + // Read the Modem Control Register. + // + Mcr =3D SerialPortReadRegister (BaseAddress, R_UART_MCR, UseMmio, Str= ide); + Mcr &=3D (~(B_UART_MCR_DTRC | B_UART_MCR_RTS)); + + if ((Control & EFI_SERIAL_DATA_TERMINAL_READY) =3D=3D EFI_SERIAL_DATA_= TERMINAL_READY) { + Mcr |=3D B_UART_MCR_DTRC; + } + + if ((Control & EFI_SERIAL_REQUEST_TO_SEND) =3D=3D EFI_SERIAL_REQUEST_T= O_SEND) { + Mcr |=3D B_UART_MCR_RTS; + } + + // + // Write the Modem Control Register. + // + SerialPortWriteRegister (BaseAddress, R_UART_MCR, Mcr, UseMmio, Stride= ); + Count++; + } + + return RETURN_SUCCESS; +} + +/** + Retrieve the status of the control bits on a serial device. + + @param Control A pointer to return the current control si= gnals 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 op= eration. + @retval RETURN_DEVICE_ERROR The serial device is not functioning corre= ctly. + +**/ +RETURN_STATUS +EFIAPI +SerialPortGetControl ( + OUT UINT32 *Control + ) +{ + UINTN BaseAddress; + BOOLEAN UseMmio; + UINT8 Msr; + UINT8 Mcr; + UINT8 Lsr; + UINT8 Count; + UINT8 Stride; + + Count =3D 0; + while (Count < mUartCount) { + BaseAddress =3D mUartInfo[Count].BaseAddress; + UseMmio =3D mUartInfo[Count].UseMmio; + Stride =3D mUartInfo[Count].RegisterStride; + + if (BaseAddress =3D=3D 0) { + return RETURN_UNSUPPORTED; + } + + *Control =3D 0; + + // + // Read the Modem Status Register. + // + Msr =3D SerialPortReadRegister (BaseAddress, R_UART_MSR, UseMmio,=20 + Stride); + + if ((Msr & B_UART_MSR_CTS) =3D=3D B_UART_MSR_CTS) { + *Control |=3D EFI_SERIAL_CLEAR_TO_SEND; + } + + if ((Msr & B_UART_MSR_DSR) =3D=3D B_UART_MSR_DSR) { + *Control |=3D EFI_SERIAL_DATA_SET_READY; + } + + if ((Msr & B_UART_MSR_RI) =3D=3D B_UART_MSR_RI) { + *Control |=3D EFI_SERIAL_RING_INDICATE; + } + + if ((Msr & B_UART_MSR_DCD) =3D=3D B_UART_MSR_DCD) { + *Control |=3D EFI_SERIAL_CARRIER_DETECT; + } + + // + // Read the Modem Control Register. + // + Mcr =3D SerialPortReadRegister (BaseAddress, R_UART_MCR, UseMmio,=20 + Stride); + + if ((Mcr & B_UART_MCR_DTRC) =3D=3D B_UART_MCR_DTRC) { + *Control |=3D EFI_SERIAL_DATA_TERMINAL_READY; + } + + if ((Mcr & B_UART_MCR_RTS) =3D=3D B_UART_MCR_RTS) { + *Control |=3D EFI_SERIAL_REQUEST_TO_SEND; + } + + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { + *Control |=3D EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE; + } + + // + // Read the Line Status Register. + // + Lsr =3D SerialPortReadRegister (BaseAddress, R_UART_LSR, UseMmio,=20 + Stride); + + if ((Lsr & (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) =3D=3D (B_UART_LSR_TE= MT | B_UART_LSR_TXRDY)) { + *Control |=3D EFI_SERIAL_OUTPUT_BUFFER_EMPTY; + } + + if ((Lsr & B_UART_LSR_RXRDY) =3D=3D 0) { + *Control |=3D EFI_SERIAL_INPUT_BUFFER_EMPTY; + } + Count++; + } + + return RETURN_SUCCESS; +} + +/** + Sets the baud rate, receive FIFO depth, transmit/receice time out,=20 +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 ReveiveFifoDepth 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 d= evice's default time + out value. + On output, the value actually set. + @param Parity The type of parity to use on this serial devic= e. A Parity value of + DefaultParity will use the device's default pa= rity value. + On output, the value actually set. + @param DataBits The number of data bits to use on the serial d= evice. A DataBits + vaule 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 ser= ial device. + @retval RETURN_UNSUPPORTED The serial device does not support thi= s operation. + @retval RETURN_INVALID_PARAMETER One or more of the attributes has an u= nsupported value. + @retval RETURN_DEVICE_ERROR The serial device is not functioning c= orrectly. + +**/ +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 + ) +{ + UINTN BaseAddress; + BOOLEAN UseMmio; + UINT32 SerialBaudRate; + UINTN Divisor; + UINT8 Lcr; + UINT8 LcrData; + UINT8 LcrParity; + UINT8 LcrStop; + UINT8 Count; + UINT8 Stride; + + Count =3D 0; + while (Count < mUartCount) { + BaseAddress =3D mUartInfo[Count].BaseAddress; + UseMmio =3D mUartInfo[Count].UseMmio; + Stride =3D mUartInfo[Count].RegisterStride; + + if (BaseAddress =3D=3D 0) { + return RETURN_UNSUPPORTED; + } + + // + // Check for default settings and fill in actual values. + // + if (*BaudRate =3D=3D 0) { + *BaudRate =3D mUartInfo[Count].BaudRate; + } + + SerialBaudRate =3D (UINT32)*BaudRate; + + if (*DataBits =3D=3D 0) { + LcrData =3D (UINT8)(PcdGet8 (PcdSerialLineControl) & 0x3); + *DataBits =3D LcrData + 5; + } else { + if ((*DataBits < 5) || (*DataBits > 8)) { + return RETURN_INVALID_PARAMETER; + } + + // + // Map 5..8 to 0..3 + // + LcrData =3D (UINT8)(*DataBits - (UINT8)5); + } + + if (*Parity =3D=3D DefaultParity) { + LcrParity =3D (UINT8)((PcdGet8 (PcdSerialLineControl) >> 3) & 0x7); + switch (LcrParity) { + case 0: + *Parity =3D NoParity; + break; + + case 3: + *Parity =3D EvenParity; + break; + + case 1: + *Parity =3D OddParity; + break; + + case 7: + *Parity =3D SpaceParity; + break; + + case 5: + *Parity =3D MarkParity; + break; + + default: + break; + } + } else { + switch (*Parity) { + case NoParity: + LcrParity =3D 0; + break; + + case EvenParity: + LcrParity =3D 3; + break; + + case OddParity: + LcrParity =3D 1; + break; + + case SpaceParity: + LcrParity =3D 7; + break; + + case MarkParity: + LcrParity =3D 5; + break; + + default: + return RETURN_INVALID_PARAMETER; + } + } + + if (*StopBits =3D=3D DefaultStopBits) { + LcrStop =3D (UINT8)((PcdGet8 (PcdSerialLineControl) >> 2) & 0x1); + switch (LcrStop) { + case 0: + *StopBits =3D OneStopBit; + break; + + case 1: + if (*DataBits =3D=3D 5) { + *StopBits =3D OneFiveStopBits; + } else { + *StopBits =3D TwoStopBits; + } + + break; + + default: + break; + } + } else { + switch (*StopBits) { + case OneStopBit: + LcrStop =3D 0; + break; + + case OneFiveStopBits: + case TwoStopBits: + LcrStop =3D 1; + break; + + default: + return RETURN_INVALID_PARAMETER; + } + } + + // + // Calculate divisor for baud generator + // Ref_Clk_Rate / Baud_Rate / 16 + // + Divisor =3D PcdGet32 (PcdSerialClockRate) / (SerialBaudRate * 16); + if ((PcdGet32 (PcdSerialClockRate) % (SerialBaudRate * 16)) >=3D Seria= lBaudRate * 8) { + Divisor++; + } + + // + // Configure baud rate + // + SerialPortWriteRegister (BaseAddress, R_UART_LCR, B_UART_LCR_DLAB, Use= Mmio, Stride); + SerialPortWriteRegister (BaseAddress, R_UART_BAUD_HIGH, (UINT8)(Diviso= r >> 8), UseMmio, Stride); + SerialPortWriteRegister (BaseAddress, R_UART_BAUD_LOW,=20 + (UINT8)(Divisor & 0xff), UseMmio, Stride); + + // + // Clear DLAB and configure Data Bits, Parity, and Stop Bits. + // Strip reserved bits from line control value + // + Lcr =3D (UINT8)((LcrParity << 3) | (LcrStop << 2) | LcrData); + SerialPortWriteRegister (BaseAddress, R_UART_LCR, (UINT8)(Lcr & 0x3F),= UseMmio, Stride); + Count++; + } + + return RETURN_SUCCESS; +} diff --git a/UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibH= ob.inf b/UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibHob.i= nf new file mode 100644 index 0000000000..ac857d3eea --- /dev/null +++ b/UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibHob.i +++ nf @@ -0,0 +1,39 @@ +## @file +# SerialPortLib instance for UART information retrieved from bootloader. +# +# Copyright (c) 2022, Intel Corporation. All rights reserved.
# # =20 +SPDX-License-Identifier: BSD-2-Clause-Patent # ## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D BaseSerialPortLibHob + FILE_GUID =3D d8d22930-e8ec-469f-8184-5a069149b2ff + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D SerialPortLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + PcdLib + IoLib + HobLib + TimerLib + +[Sources] + BaseSerialPortLibHob.c + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialLineControl + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialFifoControl + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialExtendedTxFifoSize + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl + +[Guids] + gUniversalPayloadSerialPortInfoGuid -- 2.30.2.windows.1