From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from EUR05-DB8-obe.outbound.protection.outlook.com (EUR05-DB8-obe.outbound.protection.outlook.com [40.107.20.82]) by mx.groups.io with SMTP id smtpd.web12.17870.1581313732845775842 for ; Sun, 09 Feb 2020 21:48:54 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@nxp.com header.s=selector2 header.b=BL6F5kpc; spf=pass (domain: nxp.com, ip: 40.107.20.82, mailfrom: pankaj.bansal@nxp.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=RBwMbUCrDlZC8tc6PJ/w5EG2bkxnfsCu33xdMidstdTxGpEbgGscZnoR62VsOg6GZ1IVSW27zfyd5AGqMjSAk5N8ZIjwN9NLqTezMrRGu4bAOGwJx8/BKCreGCa++pf18Ug61w2xkgAEM7uQlTY80O4VJITig+204jkidMDgN7l1CaadfRl5G8hBC7lLOAUPYEAPtUd9h8rVzCdWqZj4Mzw1ceOED42oFEdht9LK7IdG0qA7DwKcAMn3QFRUqehPBEN38IMNK74T9eEFUDUphEq9X4iCVw3qPIrYm1HFNsSQNe68Tadr6Xgj2WQMAIwkaLfAS+XabRVMSOJnBoeFOg== 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-SenderADCheck; bh=sJfGlICyiHrp4upufQCgOAF2I++9lb9FrV/OXGYFgcc=; b=klZL0IR6iwDwavV362KzLJkx/KFJ9Qthtrz855ZOy2eVXdY1gRp2617DziRQJx3m1T78um+EXemGUUAOmKI2VtFMZIpltCr+xx20wrihAHD4PttgbwjbiX8TXK805J0ctZDqoBhqkHDHhq4DF+pfJWADqLi5hmmsGByXQoHL0WvcqZKS6Naht9ALCOE/jT/tQEOshuAu6SLTzafvjRkDFfMbBBvCZVLCOSgKzBdGEB5Yr7C0sXfndzl+h1m8l1HOsetYCv11jlDLhvp4E0VDcVDtkJKY44LHc6TV3leBjno6SFDmA9ThxQ9wIZ7AcHKzPYzQsaLOc5y45aLsJMGJHg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nxp.com; dmarc=pass action=none header.from=nxp.com; dkim=pass header.d=nxp.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=sJfGlICyiHrp4upufQCgOAF2I++9lb9FrV/OXGYFgcc=; b=BL6F5kpctFl3mQx3T3XrIaT+4mxi58EEEPobI4qvZRMGalCeqwQB1K7/+Rlzcl6fXNNXx82rr1eKH6ClNNW2qCYKmeBgfpO4Qr4deRu2Xc4RXr+pzABoQZ1BgwYTDJJMy2e5RPi4kOEW2CM0wC3Qc5G6beFgjYTXFY5PchCyMVU= Received: from VI1PR0401MB2496.eurprd04.prod.outlook.com (10.168.65.10) by VI1PR0401MB2400.eurprd04.prod.outlook.com (10.169.135.15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2707.21; Mon, 10 Feb 2020 05:48:48 +0000 Received: from VI1PR0401MB2496.eurprd04.prod.outlook.com ([fe80::8823:663d:c6ed:cbd6]) by VI1PR0401MB2496.eurprd04.prod.outlook.com ([fe80::8823:663d:c6ed:cbd6%12]) with mapi id 15.20.2707.028; Mon, 10 Feb 2020 05:48:47 +0000 From: "Pankaj Bansal" To: Leif Lindholm CC: Meenakshi Aggarwal , Michael D Kinney , Varun Sethi , "devel@edk2.groups.io" Subject: Re: [PATCH 04/19] Silicon/NXP: Remove DuartLib and use BaseSerialPortLib16550 Thread-Topic: [PATCH 04/19] Silicon/NXP: Remove DuartLib and use BaseSerialPortLib16550 Thread-Index: AQHV3YePha0Y4sKF5EKXWHPgz4TOjKgRlEgAgAJYNKA= Date: Mon, 10 Feb 2020 05:48:47 +0000 Message-ID: References: <20200207124328.8723-1-pankaj.bansal@nxp.com> <20200207124328.8723-5-pankaj.bansal@nxp.com> <20200208174620.GG23627@bivouac.eciton.net> In-Reply-To: <20200208174620.GG23627@bivouac.eciton.net> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: spf=none (sender IP is ) smtp.mailfrom=pankaj.bansal@nxp.com; x-originating-ip: [92.120.1.65] x-ms-publictraffictype: Email x-ms-office365-filtering-ht: Tenant x-ms-office365-filtering-correlation-id: 02506486-c188-4ab4-1d28-08d7adece60d x-ms-traffictypediagnostic: VI1PR0401MB2400:|VI1PR0401MB2400: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:9508; x-forefront-prvs: 03094A4065 x-forefront-antispam-report: SFV:NSPM;SFS:(10009020)(4636009)(136003)(376002)(366004)(39860400002)(396003)(346002)(189003)(199004)(7696005)(478600001)(86362001)(4326008)(71200400001)(8936002)(44832011)(19627235002)(6506007)(53546011)(76116006)(966005)(30864003)(9686003)(6916009)(54906003)(45080400002)(52536014)(66946007)(316002)(66476007)(66556008)(55016002)(64756008)(66446008)(26005)(186003)(2906002)(5660300002)(8676002)(33656002)(81166006)(81156014)(326664003)(579004)(559001)(569007);DIR:OUT;SFP:1101;SCL:1;SRVR:VI1PR0401MB2400;H:VI1PR0401MB2496.eurprd04.prod.outlook.com;FPR:;SPF:None;LANG:en;PTR:InfoNoRecords;MX:1;A:1; received-spf: None (protection.outlook.com: nxp.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: cws+Ulxc8NpoiAXyivN1jTLvEGJYR7/2b636b+jI0m/G12tjk+LymieWqDXt2qjn/srDClbfhSyOcTmsZp4FzYfxdxxwLr7vCuUfYlsDi/XThcObek3wsjOGf0dBUgkXjx9lXjlttcmYkSvDPl9WHdhT3xFIxv0pDOgd9Ub95YqgufRi0HN3KbOTGZP0Akem7iemoyU1+bRerWEUQT7UmmbzCde1vALOzFuyp3m4j7iUEL6rkehG/8k474OvQFYO1Y2ZPyCs//Wn16UwrEHTCIIbVLPeraaGooWKcwpBt0XYYe4lRJFSg/rHGWBbvWqDHqH/qPDe1zuFSMPVMV7bH6PKUuRXR5fkPbgBkxTfi4bC3hxDrztRfG9XV+t4GM9wACVL/38pjacJMe+l6IkCzOCpopS3DVT7vWvHFQ6qCDdXmm78d3LyyMcnKVn4Zruos7ezKt2J8GEpahKjsgyJi9nYhGaerrzRIGYLANWXSGBtinMtlTwZSm38CBn6O7g3zzJVxqXlwSCOlXm1+zxeGYlLU3sgOzk459E3kY3z+RThERGa9wPjXmicGXHaoRMAzu9WVjfjNtF7VEw5akhH1A== x-ms-exchange-antispam-messagedata: 36gbcj0hqk32o6dMKfK4JBc6D4QEDuE/QDbxObfMZlhpI06Nko5uZ2GPtquKshXgka4dxYB4HxXXPdfBCSXSyGVMzSuG+4QH6jsRcqjrQUR04xbZg1GPr8gt/Ikv8AoE5PlntN1F/s0xNfaQhgS1Jw== MIME-Version: 1.0 X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 02506486-c188-4ab4-1d28-08d7adece60d X-MS-Exchange-CrossTenant-originalarrivaltime: 10 Feb 2020 05:48:47.8101 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: hUPuiZss0M9+/+chBf4Dr63721RBULeLedKY/jbTyqdv30pEfrs8tGGjdYnD3qfT5cwZD5q6oi4QkkSC+NbTMQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR0401MB2400 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable > -----Original Message----- > From: Leif Lindholm > Sent: Saturday, February 8, 2020 11:16 PM > To: Pankaj Bansal > Cc: Meenakshi Aggarwal ; Michael D Kinney > ; Varun Sethi ; > devel@edk2.groups.io > Subject: Re: [PATCH 04/19] Silicon/NXP: Remove DuartLib and use > BaseSerialPortLib16550 >=20 > On Fri, Feb 07, 2020 at 18:13:13 +0530, Pankaj Bansal wrote: > > UART in LS1043A conforms to ns16550 register set. so we can use the > > SerialPortLib16550 from MdeModulePkg. >=20 > 1) This patch adds a new library and deletes an existing one - those > are two operationsand hence should be two patches. OK. I can split the patch in two >=20 > 2) That is irrelevant, because if you can use BaseSerialPortLib16550, > then use BaseSerialPortLib16550. Copying an existing library in > order to make some minor tweaks is not an option. If you look at the [PATCH 05/19] NXP/BaseSerialPortLib16550: remove SerialP= ortInitalize functionality (https://edk2.groups.io/g/devel/message/54011?p=3D,,,20,0,0,0::Created,,Bas= eSerialPortLib16550,20,2,0,71046325) I have removed SerialPortInitalize functionality, which I am guessing would= not work for each platform using BaseSerialPortLib16550 Which is why I have forked the BaseSerialPortLib16550 for NXP platforms. >=20 > > We have removed the PCIe specific part from the library and also added > > the APIs to get the UART clock from SOC lib instead of using the fixed > > PCD. >=20 > So, what you need to do is update BaseSerialPortLib16550 to be usable > for you. This library is already used by several ARM platforms that > don't actually implement PCIe. Again, I can do that In the similar way we have done for PL011 (https://git= hub.com/tianocore/edk2/commit/cbba5ca104fbc8baa0c613951e833e1a07bb34df) But as I stated above, this is an unnecessary overhead which increases code= size as well as execution time. Both of which we want to avoid. That is why we have forked BaseSerialPortLib16550 (and even PL011SerialPort= Lib for that matter for LX2160A) for NXP platforms. >=20 > > Signed-off-by: Pankaj Bansal > > --- > > Silicon/NXP/LS1043A/LS1043A.dsc.inc | 2 +- > > .../BaseSerialPortLib16550.c | 804 ++++++++++++++++++ > > .../BaseSerialPortLib16550.inf | 39 + > > .../BaseSerialPortLib16550.uni | 17 + >=20 > Please don't leave out the --stat and --stat-graph-width when > following the format-patch instructions at > https://eur01.safelinks.protection.outlook.com/?url=3Dhttps%3A%2F%2Fgithu= b.co > m%2Ftianocore%2Ftianocore.github.io%2Fwiki%2FLaszlo%2527s-unkempt-git- > guide-for-edk2-contributors-and- > maintainers&data=3D02%7C01%7Cpankaj.bansal%40nxp.com%7C696ddff166 > 5a4367502608d7acbed0e8%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C > 0%7C637167807871085424&sdata=3D8tHGzseG00MNL1Hc62fFIxKGqcl0quW > Rq%2Bc9W%2BQRFRU%3D&reserved=3D0 >=20 > / > Leif >=20 > > Silicon/NXP/Library/DUartPortLib/DUart.h | 122 --- > > .../NXP/Library/DUartPortLib/DUartPortLib.c | 364 -------- > > .../NXP/Library/DUartPortLib/DUartPortLib.inf | 34 - > > 7 files changed, 861 insertions(+), 521 deletions(-) > > create mode 100644 > Silicon/NXP/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.c > > create mode 100644 > Silicon/NXP/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf > > create mode 100644 > Silicon/NXP/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.uni > > delete mode 100644 Silicon/NXP/Library/DUartPortLib/DUart.h > > delete mode 100644 Silicon/NXP/Library/DUartPortLib/DUartPortLib.c > > delete mode 100644 Silicon/NXP/Library/DUartPortLib/DUartPortLib.inf > > > > diff --git a/Silicon/NXP/LS1043A/LS1043A.dsc.inc > b/Silicon/NXP/LS1043A/LS1043A.dsc.inc > > index 8790db6ff8..754eff396a 100644 > > --- a/Silicon/NXP/LS1043A/LS1043A.dsc.inc > > +++ b/Silicon/NXP/LS1043A/LS1043A.dsc.inc > > @@ -9,7 +9,7 @@ > > > > [LibraryClasses.common] > > SocLib|Silicon/NXP/Library/SocLib/LS1043aSocLib.inf > > - SerialPortLib|Silicon/NXP/Library/DUartPortLib/DUartPortLib.inf > > + > SerialPortLib|Silicon/NXP/Library/BaseSerialPortLib16550/BaseSerialPortLi= b165 > 50.inf > > > > > ################################################################# > ############### > > # > > diff --git > a/Silicon/NXP/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.c > b/Silicon/NXP/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.c > > new file mode 100644 > > index 0000000000..2c5c54ac7d > > --- /dev/null > > +++ b/Silicon/NXP/Library/BaseSerialPortLib16550/BaseSerialPortLib16550= .c > > @@ -0,0 +1,804 @@ > > +/** @file > > + 16550 UART Serial Port library functions > > + > > + (C) Copyright 2014 Hewlett-Packard Development Company, L.P.
> > + Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved. > > + Copyright (c) 2018, AMD Incorporated. All rights reserved.
> > + Copyright 2020 NXP > > + > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > + > > +**/ > > + > > +#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 > > + > > +extern > > +UINT64 > > +GetBusFrequency ( > > + VOID > > + ); > > + > > +/** > > + Read an 8-bit 16550 register. If PcdSerialUseMmio is TRUE, then the= value is > read from > > + MMIO space. If PcdSerialUseMmio is FALSE, then the value is read fr= om I/O > space. The > > + parameter Offset is added to the base address of the 16550 registers= that is > specified > > + by PcdSerialRegisterBase. PcdSerialRegisterAccessWidth specifies the= MMIO > space access > > + width and defaults to 8 bit access, and supports 8 or 32 bit access. > > + > > + @param Base The base address register of UART device. > > + @param Offset The offset of the 16550 register to read. > > + > > + @return The value read from the 16550 register. > > + > > +**/ > > +UINT8 > > +SerialPortReadRegister ( > > + UINTN Base, > > + UINTN Offset > > + ) > > +{ > > + return MmioRead8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride)= ); > > +} > > + > > +/** > > + Write an 8-bit 16550 register. If PcdSerialUseMmio is TRUE, then th= e value > is written to > > + MMIO space. If PcdSerialUseMmio is FALSE, then the value is written= to I/O > space. The > > + parameter Offset is added to the base address of the 16550 registers= that is > specified > > + by PcdSerialRegisterBase. PcdSerialRegisterAccessWidth specifies the= MMIO > space access > > + width and defaults to 8 bit access, and supports 8 or 32 bit access. > > + > > + @param Base The base address register of UART device. > > + @param Offset The offset of the 16550 register to write. > > + @param Value The value to write to the 16550 register specified b= y Offset. > > + > > + @return The value written to the 16550 register. > > + > > +**/ > > +UINT8 > > +SerialPortWriteRegister ( > > + UINTN Base, > > + UINTN Offset, > > + UINT8 Value > > + ) > > +{ > > + return MmioWrite8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride= ), > Value); > > +} > > + > > +/** > > + Retrieve the I/O or MMIO base address register for the PCI UART devi= ce. > > + > > + This function assumes Root Bus Numer is Zero, and enables I/O and MM= IO > in PCI UART > > + Device if they are not already enabled. > > + > > + @return The base address register of the UART device. > > + > > +**/ > > +UINTN > > +GetSerialRegisterBase ( > > + VOID > > + ) > > +{ > > + return (UINTN)PcdGet64 (PcdSerialRegisterBase); > > +} > > + > > +/** > > + Return whether the hardware flow control signal allows writing. > > + > > + @param SerialRegisterBase The base address register of UART device. > > + > > + @retval TRUE The serial port is writable. > > + @retval FALSE The serial port is not writable. > > +**/ > > +BOOLEAN > > +SerialPortWritable ( > > + UINTN SerialRegisterBase > > + ) > > +{ > > + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { > > + if (PcdGetBool (PcdSerialDetectCable)) { > > + // > > + // Wait for both DSR and CTS to be set > > + // DSR is set if a cable is connected. > > + // CTS is set if it is ok to transmit data > > + // > > + // DSR CTS Description Action > > + // =3D=3D=3D =3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D > > + // 0 0 No cable connected. Wait > > + // 0 1 No cable connected. Wait > > + // 1 0 Cable connected, but not clear to send. Wait > > + // 1 1 Cable connected, and clear to send. Transmi= t > > + // > > + return (BOOLEAN) ((SerialPortReadRegister (SerialRegisterBase, > R_UART_MSR) & (B_UART_MSR_DSR | B_UART_MSR_CTS)) =3D=3D > (B_UART_MSR_DSR | B_UART_MSR_CTS)); > > + } else { > > + // > > + // Wait for both DSR and CTS to be set OR for DSR to be clear. > > + // DSR is set if a cable is connected. > > + // CTS is set if it is ok to transmit data > > + // > > + // DSR CTS Description Action > > + // =3D=3D=3D =3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D > > + // 0 0 No cable connected. Transmi= t > > + // 0 1 No cable connected. Transmi= t > > + // 1 0 Cable connected, but not clear to send. Wait > > + // 1 1 Cable connected, and clar to send. Transmi= t > > + // > > + return (BOOLEAN) ((SerialPortReadRegister (SerialRegisterBase, > R_UART_MSR) & (B_UART_MSR_DSR | B_UART_MSR_CTS)) !=3D > (B_UART_MSR_DSR)); > > + } > > + } > > + > > + return TRUE; > > +} > > + > > +/** > > + 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 initial= ized. > > + > > +**/ > > +RETURN_STATUS > > +EFIAPI > > +SerialPortInitialize ( > > + VOID > > + ) > > +{ > > + UINTN SerialRegisterBase; > > + UINT32 Divisor; > > + UINT32 CurrentDivisor; > > + BOOLEAN Initialized; > > + UINT64 SerialClock; > > + > > + // > > + // Perform platform specific initialization required to enable use o= f the > 16550 device > > + // at the location specified by PcdSerialUseMmio and PcdSerialRegist= erBase. > > + // > > + SerialClock =3D GetBusFrequency (); > > + if (SerialClock =3D=3D 0) { > > + return EFI_DEVICE_ERROR; > > + } > > + > > + // > > + // Calculate divisor for baud generator > > + // Ref_Clk_Rate / Baud_Rate / 16 > > + // > > + Divisor =3D SerialClock / (PcdGet32 (PcdSerialBaudRate) * 16); > > + if ((SerialClock % (PcdGet32 (PcdSerialBaudRate) * 16)) >=3D PcdGet3= 2 > (PcdSerialBaudRate) * 8) { > > + Divisor++; > > + } > > + > > + // > > + // Get the base address of the serial port in either I/O or MMIO spa= ce > > + // > > + SerialRegisterBase =3D GetSerialRegisterBase (); > > + if (SerialRegisterBase =3D=3D 0) { > > + return RETURN_DEVICE_ERROR; > > + } > > + > > + // > > + // See if the serial port is already initialized > > + // > > + Initialized =3D TRUE; > > + if ((SerialPortReadRegister (SerialRegisterBase, R_UART_LCR) & 0x3F)= !=3D > (PcdGet8 (PcdSerialLineControl) & 0x3F)) { > > + Initialized =3D FALSE; > > + } > > + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, > (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_LCR) | > B_UART_LCR_DLAB)); > > + CurrentDivisor =3D SerialPortReadRegister (SerialRegisterBase, > R_UART_BAUD_HIGH) << 8; > > + CurrentDivisor |=3D (UINT32) SerialPortReadRegister (SerialRegisterB= ase, > R_UART_BAUD_LOW); > > + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, > (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_LCR) & > ~B_UART_LCR_DLAB)); > > + if (CurrentDivisor !=3D Divisor) { > > + Initialized =3D FALSE; > > + } > > + if (Initialized) { > > + return RETURN_SUCCESS; > > + } > > + > > + // > > + // Wait for the serial port to be ready. > > + // Verify that both the transmit FIFO and the shift register are emp= ty. > > + // > > + while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & > (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) !=3D (B_UART_LSR_TEMT | > B_UART_LSR_TXRDY)); > > + > > + // > > + // Configure baud rate > > + // > > + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, > B_UART_LCR_DLAB); > > + SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_HIGH, (UINT= 8) > (Divisor >> 8)); > > + SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_LOW, (UINT8= ) > (Divisor & 0xff)); > > + > > + // > > + // Clear DLAB and configure Data Bits, Parity, and Stop Bits. > > + // Strip reserved bits from PcdSerialLineControl > > + // > > + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8)(Pcd= Get8 > (PcdSerialLineControl) & 0x3F)); > > + > > + // > > + // Enable and reset FIFOs > > + // Strip reserved bits from PcdSerialFifoControl > > + // > > + SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, 0x00); > > + SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, (UINT8)(Pcd= Get8 > (PcdSerialFifoControl) & (B_UART_FCR_FIFOE | B_UART_FCR_FIFO64))); > > + > > + // > > + // Set FIFO Polled Mode by clearing IER after setting FCR > > + // > > + SerialPortWriteRegister (SerialRegisterBase, R_UART_IER, 0x00); > > + > > + // > > + // Put Modem Control Register(MCR) into its reset state of 0x00. > > + // > > + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, 0x00); > > + > > + 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 returne= d. > > + If the return value is less than NumberOfBytes, then the write opera= tion > 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 de= vice. > > + > > + @retval 0 NumberOfBytes is 0. > > + @retval >0 The number of bytes written to the serial d= evice. > > + If this value is less than NumberOfBytes, t= hen the write > operation failed. > > + > > +**/ > > +UINTN > > +EFIAPI > > +SerialPortWrite ( > > + IN UINT8 *Buffer, > > + IN UINTN NumberOfBytes > > + ) > > +{ > > + UINTN SerialRegisterBase; > > + UINTN Result; > > + UINTN Index; > > + UINTN FifoSize; > > + > > + if (Buffer =3D=3D NULL) { > > + return 0; > > + } > > + > > + SerialRegisterBase =3D GetSerialRegisterBase (); > > + if (SerialRegisterBase =3D=3D0) { > > + return 0; > > + } > > + > > + if (NumberOfBytes =3D=3D 0) { > > + // > > + // Flush the hardware > > + // > > + > > + // > > + // Wait for both the transmit FIFO and shift register empty. > > + // > > + while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & > (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) !=3D (B_UART_LSR_TEMT | > B_UART_LSR_TXRDY)); > > + > > + // > > + // Wait for the hardware flow control signal > > + // > > + while (!SerialPortWritable (SerialRegisterBase)); > > + return 0; > > + } > > + > > + // > > + // Compute the maximum size of the Tx FIFO > > + // > > + FifoSize =3D 1; > > + if ((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); > > + } > > + } > > + > > + Result =3D NumberOfBytes; > > + while (NumberOfBytes !=3D 0) { > > + // > > + // Wait for the serial port to be ready, to make sure both the tra= nsmit FIFO > > + // and shift register empty. > > + // > > + while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & > (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) !=3D (B_UART_LSR_TEMT | > B_UART_LSR_TXRDY)); > > + > > + // > > + // Fill then entire Tx FIFO > > + // > > + for (Index =3D 0; Index < FifoSize && NumberOfBytes !=3D 0; Index+= +, > NumberOfBytes--, Buffer++) { > > + // > > + // Wait for the hardware flow control signal > > + // > > + while (!SerialPortWritable (SerialRegisterBase)); > > + > > + // > > + // Write byte to the transmit buffer. > > + // > > + SerialPortWriteRegister (SerialRegisterBase, R_UART_TXBUF, *Buff= er); > > + } > > + } > > + return Result; > > +} > > + > > +/** > > + Reads data from a serial device into a buffer. > > + > > + @param Buffer Pointer to the data buffer to store the dat= a read from > the serial device. > > + @param NumberOfBytes Number of bytes to read from the serial dev= ice. > > + > > + @retval 0 NumberOfBytes is 0. > > + @retval >0 The number of bytes read from the serial de= vice. > > + If this value is less than NumberOfBytes, t= hen the read > operation failed. > > + > > +**/ > > +UINTN > > +EFIAPI > > +SerialPortRead ( > > + OUT UINT8 *Buffer, > > + IN UINTN NumberOfBytes > > + ) > > +{ > > + UINTN SerialRegisterBase; > > + UINTN Result; > > + UINT8 Mcr; > > + > > + if (NULL =3D=3D Buffer) { > > + return 0; > > + } > > + > > + SerialRegisterBase =3D GetSerialRegisterBase (); > > + if (SerialRegisterBase =3D=3D0) { > > + return 0; > > + } > > + > > + Mcr =3D (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_M= CR) & > ~B_UART_MCR_RTS); > > + > > + for (Result =3D 0; NumberOfBytes-- !=3D 0; Result++, Buffer++) { > > + // > > + // Wait for the serial port to have some data. > > + // > > + while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & > B_UART_LSR_RXRDY) =3D=3D 0) { > > + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { > > + // > > + // Set RTS to let the peer send some data > > + // > > + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, (UINT= 8)(Mcr > | B_UART_MCR_RTS)); > > + } > > + } > > + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { > > + // > > + // Clear RTS to prevent peer from sending data > > + // > > + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, Mcr); > > + } > > + > > + // > > + // Read byte from the receive buffer. > > + // > > + *Buffer =3D SerialPortReadRegister (SerialRegisterBase, R_UART_RXB= UF); > > + } > > + > > + return Result; > > +} > > + > > + > > +/** > > + Polls a serial device to see if there is any data waiting to be read= . > > + > > + Polls aserial 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 TRU= E is > returned. > > + If there is no data waiting to be read from the serial device, then = FALSE is > returned. > > + > > + @retval TRUE Data is waiting to be read from the serial = device. > > + @retval FALSE There is no data waiting to be read from th= e serial > device. > > + > > +**/ > > +BOOLEAN > > +EFIAPI > > +SerialPortPoll ( > > + VOID > > + ) > > +{ > > + UINTN SerialRegisterBase; > > + > > + SerialRegisterBase =3D GetSerialRegisterBase (); > > + if (SerialRegisterBase =3D=3D0) { > > + return FALSE; > > + } > > + > > + // > > + // Read the serial port status > > + // > > + if ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & > B_UART_LSR_RXRDY) !=3D 0) { > > + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { > > + // > > + // Clear RTS to prevent peer from sending data > > + // > > + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, > (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_MCR) & > ~B_UART_MCR_RTS)); > > + } > > + return TRUE; > > + } > > + > > + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { > > + // > > + // Set RTS to let the peer send some data > > + // > > + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, > (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_MCR) | > B_UART_MCR_RTS)); > > + } > > + > > + return FALSE; > > +} > > + > > +/** > > + Sets the control bits on a serial device. > > + > > + @param Control Sets the bits of Control that are sett= able. > > + > > + @retval RETURN_SUCCESS The new control bits were set on the s= erial > device. > > + @retval RETURN_UNSUPPORTED The serial device does not support thi= s > operation. > > + @retval RETURN_DEVICE_ERROR The serial device is not functioning > correctly. > > + > > +**/ > > +RETURN_STATUS > > +EFIAPI > > +SerialPortSetControl ( > > + IN UINT32 Control > > + ) > > +{ > > + UINTN SerialRegisterBase; > > + UINT8 Mcr; > > + > > + // > > + // First determine the parameter is invalid. > > + // > > + if ((Control & (~(EFI_SERIAL_REQUEST_TO_SEND | > EFI_SERIAL_DATA_TERMINAL_READY | > > + EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE))) !=3D 0)= { > > + return RETURN_UNSUPPORTED; > > + } > > + > > + SerialRegisterBase =3D GetSerialRegisterBase (); > > + if (SerialRegisterBase =3D=3D0) { > > + return RETURN_UNSUPPORTED; > > + } > > + > > + // > > + // Read the Modem Control Register. > > + // > > + Mcr =3D SerialPortReadRegister (SerialRegisterBase, R_UART_MCR); > > + 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_TO_SEND) { > > + Mcr |=3D B_UART_MCR_RTS; > > + } > > + > > + // > > + // Write the Modem Control Register. > > + // > > + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, Mcr); > > + > > + return RETURN_SUCCESS; > > +} > > + > > +/** > > + Retrieve the status of the control bits on a serial device. > > + > > + @param Control A pointer to return the current contro= l signals from > the serial device. > > + > > + @retval RETURN_SUCCESS The control bits were read from the se= rial > device. > > + @retval RETURN_UNSUPPORTED The serial device does not support thi= s > operation. > > + @retval RETURN_DEVICE_ERROR The serial device is not functioning > correctly. > > + > > +**/ > > +RETURN_STATUS > > +EFIAPI > > +SerialPortGetControl ( > > + OUT UINT32 *Control > > + ) > > +{ > > + UINTN SerialRegisterBase; > > + UINT8 Msr; > > + UINT8 Mcr; > > + UINT8 Lsr; > > + > > + SerialRegisterBase =3D GetSerialRegisterBase (); > > + if (SerialRegisterBase =3D=3D0) { > > + return RETURN_UNSUPPORTED; > > + } > > + > > + *Control =3D 0; > > + > > + // > > + // Read the Modem Status Register. > > + // > > + Msr =3D SerialPortReadRegister (SerialRegisterBase, R_UART_MSR); > > + > > + 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 (SerialRegisterBase, R_UART_MCR); > > + > > + 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 (SerialRegisterBase, R_UART_LSR); > > + > > + if ((Lsr & (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) =3D=3D > (B_UART_LSR_TEMT | 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; > > + } > > + > > + return RETURN_SUCCESS; > > +} > > + > > +/** > > + Sets the baud rate, receive FIFO depth, transmit/receice time out, p= arity, > > + 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 rec= eive > 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 charac= ter in > microseconds. > > + This timeout applies to both the transmit = and receive side of > the > > + interface. A Timeout value of 0 will use t= he device's default > time > > + out value. > > + On output, the value actually set. > > + @param Parity The type of parity to use on this serial d= evice. A Parity > value of > > + DefaultParity will use the device's defaul= t parity value. > > + On output, the value actually set. > > + @param DataBits The number of data bits to use on the seri= al device. > A DataBits > > + vaule of 0 will use the device's default d= ata bit setting. > > + On output, the value actually set. > > + @param StopBits The number of stop bits to use on this ser= ial device. > A StopBits > > + value of DefaultStopBits will use the devi= ce'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 functioni= ng > 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 > > + ) > > +{ > > + UINTN SerialRegisterBase; > > + UINT32 SerialBaudRate; > > + UINTN Divisor; > > + UINT8 Lcr; > > + UINT8 LcrData; > > + UINT8 LcrParity; > > + UINT8 LcrStop; > > + UINT64 SerialClock; > > + > > + SerialRegisterBase =3D GetSerialRegisterBase (); > > + if (SerialRegisterBase =3D=3D0) { > > + return RETURN_UNSUPPORTED; > > + } > > + > > + SerialClock =3D GetBusFrequency (); > > + if (SerialClock =3D=3D 0) { > > + return EFI_DEVICE_ERROR; > > + } > > + > > + // > > + // Check for default settings and fill in actual values. > > + // > > + if (*BaudRate =3D=3D 0) { > > + *BaudRate =3D PcdGet32 (PcdSerialBaudRate); > > + } > > + 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 SerialClock / (SerialBaudRate * 16); > > + if ((SerialClock % (SerialBaudRate * 16)) >=3D SerialBaudRate * 8) { > > + Divisor++; > > + } > > + > > + // > > + // Configure baud rate > > + // > > + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, > B_UART_LCR_DLAB); > > + SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_HIGH, (UINT= 8) > (Divisor >> 8)); > > + SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_LOW, (UINT8= ) > (Divisor & 0xff)); > > + > > + // > > + // 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 (SerialRegisterBase, R_UART_LCR, (UINT8) (Lc= r & > 0x3F)); > > + > > + return RETURN_SUCCESS; > > +} > > + > > diff --git > a/Silicon/NXP/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf > b/Silicon/NXP/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf > > new file mode 100644 > > index 0000000000..45ae9dc0af > > --- /dev/null > > +++ b/Silicon/NXP/Library/BaseSerialPortLib16550/BaseSerialPortLib16550= .inf > > @@ -0,0 +1,39 @@ > > +## @file > > +# SerialPortLib instance for 16550 UART. > > +# > > +# Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<= BR> > > +# Copyright 2020 NXP > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > +# > > +## > > + > > +[Defines] > > + INF_VERSION =3D 0x00010005 > > + BASE_NAME =3D BaseSerialPortLib16550 > > + MODULE_UNI_FILE =3D BaseSerialPortLib16550.uni > > + FILE_GUID =3D 9E7C00CF-355A-4d4e-BF60-0428CFF95= 540 > > + MODULE_TYPE =3D BASE > > + VERSION_STRING =3D 1.1 > > + LIBRARY_CLASS =3D SerialPortLib > > + > > +[Packages] > > + MdePkg/MdePkg.dec > > + MdeModulePkg/MdeModulePkg.dec > > + > > +[LibraryClasses] > > + PcdLib > > + IoLib > > + SocLib > > + > > +[Sources] > > + BaseSerialPortLib16550.c > > + > > +[FixedPcd] > > + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl ## > CONSUMES > > + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialDetectCable ## > SOMETIMES_CONSUMES > > + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase ## > CONSUMES > > + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate ## > CONSUMES > > + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialLineControl ## > CONSUMES > > + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialFifoControl ## > CONSUMES > > + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialExtendedTxFifoSize ## > CONSUMES > > + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride ## > CONSUMES > > diff --git > a/Silicon/NXP/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.uni > b/Silicon/NXP/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.uni > > new file mode 100644 > > index 0000000000..2fefe85cf8 > > --- /dev/null > > +++ b/Silicon/NXP/Library/BaseSerialPortLib16550/BaseSerialPortLib16550= .uni > > @@ -0,0 +1,17 @@ > > +// /** @file > > +// SerialPortLib instance for 16550 UART. > > +// > > +// SerialPortLib instance for 16550 UART. > > +// > > +// Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<= BR> > > +// Copyright 2020 NXP > > +// > > +// SPDX-License-Identifier: BSD-2-Clause-Patent > > +// > > +// **/ > > + > > + > > +#string STR_MODULE_ABSTRACT #language en-US "SerialPortLib > instance for 16550 UART" > > + > > +#string STR_MODULE_DESCRIPTION #language en-US "SerialPortLib > instance for 16550 UART." > > + > > diff --git a/Silicon/NXP/Library/DUartPortLib/DUart.h > b/Silicon/NXP/Library/DUartPortLib/DUart.h > > deleted file mode 100644 > > index c71e2ce55d..0000000000 > > --- a/Silicon/NXP/Library/DUartPortLib/DUart.h > > +++ /dev/null > > @@ -1,122 +0,0 @@ > > -/** DUart.h > > -* Header defining the DUART constants (Base addresses, sizes, flags) > > -* > > -* Based on Serial I/O Port library headers available in PL011Uart.h > > -* > > -* Copyright (c) 2011-2012, ARM Limited. All rights reserved. > > -* Copyright (c) 2016, Freescale Semiconductor, Inc. All rights reserv= ed. > > -* Copyright 2017 NXP > > -* > > -* SPDX-License-Identifier: BSD-2-Clause-Patent > > -* > > -**/ > > - > > -#ifndef DUART_H_ > > -#define DUART_H_ > > - > > -// FIFO Control Register > > -#define DUART_FCR_FIFO_EN 0x01 /* Fifo enable */ > > -#define DUART_FCR_CLEAR_RCVR 0x02 /* Clear the RCVR FIFO */ > > -#define DUART_FCR_CLEAR_XMIT 0x04 /* Clear the XMIT FIFO */ > > -#define DUART_FCR_DMA_SELECT 0x08 /* For DMA applications */ > > -#define DUART_FCR_TRIGGER_MASK 0xC0 /* Mask for the FIFO trigger > range */ > > -#define DUART_FCR_TRIGGER_1 0x00 /* Mask for trigger set at 1 *= / > > -#define DUART_FCR_TRIGGER_4 0x40 /* Mask for trigger set at 4 *= / > > -#define DUART_FCR_TRIGGER_8 0x80 /* Mask for trigger set at 8 *= / > > -#define DUART_FCR_TRIGGER_14 0xC0 /* Mask for trigger set at 14 = */ > > -#define DUART_FCR_RXSR 0x02 /* Receiver soft reset */ > > -#define DUART_FCR_TXSR 0x04 /* Transmitter soft reset */ > > - > > -// Modem Control Register > > -#define DUART_MCR_DTR 0x01 /* Reserved */ > > -#define DUART_MCR_RTS 0x02 /* RTS */ > > -#define DUART_MCR_OUT1 0x04 /* Reserved */ > > -#define DUART_MCR_OUT2 0x08 /* Reserved */ > > -#define DUART_MCR_LOOP 0x10 /* Enable loopback test mode *= / > > -#define DUART_MCR_AFE 0x20 /* AFE (Auto Flow Control) */ > > -#define DUART_MCR_DMA_EN 0x04 > > -#define DUART_MCR_TX_DFR 0x08 > > - > > -// Line Control Register > > -/* > > -* Note: if the word length is 5 bits (DUART_LCR_WLEN5), then setting > > -* DUART_LCR_STOP will select 1.5 stop bits, not 2 stop bits. > > -*/ > > -#define DUART_LCR_WLS_MSK 0x03 /* character length select mas= k */ > > -#define DUART_LCR_WLS_5 0x00 /* 5 bit character length */ > > -#define DUART_LCR_WLS_6 0x01 /* 6 bit character length */ > > -#define DUART_LCR_WLS_7 0x02 /* 7 bit character length */ > > -#define DUART_LCR_WLS_8 0x03 /* 8 bit character length */ > > -#define DUART_LCR_STB 0x04 /* # stop Bits, off=3D1, on=3D= 1.5 or 2) */ > > -#define DUART_LCR_PEN 0x08 /* Parity eneble */ > > -#define DUART_LCR_EPS 0x10 /* Even Parity Select */ > > -#define DUART_LCR_STKP 0x20 /* Stick Parity */ > > -#define DUART_LCR_SBRK 0x40 /* Set Break */ > > -#define DUART_LCR_BKSE 0x80 /* Bank select enable */ > > -#define DUART_LCR_DLAB 0x80 /* Divisor latch access bit */ > > - > > -// Line Status Register > > -#define DUART_LSR_DR 0x01 /* Data ready */ > > -#define DUART_LSR_OE 0x02 /* Overrun */ > > -#define DUART_LSR_PE 0x04 /* Parity error */ > > -#define DUART_LSR_FE 0x08 /* Framing error */ > > -#define DUART_LSR_BI 0x10 /* Break */ > > -#define DUART_LSR_THRE 0x20 /* Xmit holding register empty= */ > > -#define DUART_LSR_TEMT 0x40 /* Xmitter empty */ > > -#define DUART_LSR_ERR 0x80 /* Error */ > > - > > -// Modem Status Register > > -#define DUART_MSR_DCTS 0x01 /* Delta CTS */ > > -#define DUART_MSR_DDSR 0x02 /* Reserved */ > > -#define DUART_MSR_TERI 0x04 /* Reserved */ > > -#define DUART_MSR_DDCD 0x08 /* Reserved */ > > -#define DUART_MSR_CTS 0x10 /* Clear to Send */ > > -#define DUART_MSR_DSR 0x20 /* Reserved */ > > -#define DUART_MSR_RI 0x40 /* Reserved */ > > -#define DUART_MSR_DCD 0x80 /* Reserved */ > > - > > -// Interrupt Identification Register > > -#define DUART_IIR_NO_INT 0x01 /* No interrupts pending */ > > -#define DUART_IIR_ID 0x06 /* Mask for the interrupt ID *= / > > -#define DUART_IIR_MSI 0x00 /* Modem status interrupt */ > > -#define DUART_IIR_THRI 0x02 /* Transmitter holding registe= r empty */ > > -#define DUART_IIR_RDI 0x04 /* Receiver data interrupt */ > > -#define DUART_IIR_RLSI 0x06 /* Receiver line status interr= upt */ > > - > > -// Interrupt Enable Register > > -#define DUART_IER_MSI 0x08 /* Enable Modem status interru= pt */ > > -#define DUART_IER_RLSI 0x04 /* Enable receiver line status= interrupt > */ > > -#define DUART_IER_THRI 0x02 /* Enable Transmitter holding = register > int. */ > > -#define DUART_IER_RDI 0x01 /* Enable receiver data interr= upt */ > > - > > -// LCR defaults > > -#define DUART_LCR_8N1 0x03 > > -#define DUART_LCRVAL DUART_LCR_8N1 /* 8 data, 1= stop, no > parity */ > > -#define DUART_MCRVAL (DUART_MCR_DTR | \ > > - DUART_MCR_RTS) /* RTS/DTR *= / > > -#define DUART_FCRVAL (DUART_FCR_FIFO_EN | \ > > - DUART_FCR_RXSR | \ > > - DUART_FCR_TXSR) /* Clear & e= nable FIFOs */ > > - > > -#define URBR 0x0 > > -#define UTHR 0x0 > > -#define UDLB 0x0 > > -#define UDMB 0x1 > > -#define UIER 0x1 > > -#define UIIR 0x2 > > -#define UFCR 0x2 > > -#define UAFR 0x2 > > -#define ULCR 0x3 > > -#define UMCR 0x4 > > -#define ULSR 0x5 > > -#define UMSR 0x6 > > -#define USCR 0x7 > > -#define UDSR 0x10 > > - > > -extern > > -UINT64 > > -GetBusFrequency ( > > - VOID > > - ); > > - > > -#endif /* DUART_H_ */ > > diff --git a/Silicon/NXP/Library/DUartPortLib/DUartPortLib.c > b/Silicon/NXP/Library/DUartPortLib/DUartPortLib.c > > deleted file mode 100644 > > index c3c738d3cc..0000000000 > > --- a/Silicon/NXP/Library/DUartPortLib/DUartPortLib.c > > +++ /dev/null > > @@ -1,364 +0,0 @@ > > -/** DuartPortLib.c > > - DUART (NS16550) library functions > > - > > - Based on Serial I/O Port library functions available in PL011SerialP= ortLib.c > > - > > - Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.
> > - Copyright (c) 2012 - 2013, ARM Ltd. All rights reserved.
> > - Copyright (c) 2016, Freescale Semiconductor, Inc. All rights reserve= d. > > - Copyright 2017 NXP > > - > > - SPDX-License-Identifier: BSD-2-Clause-Patent > > - > > -**/ > > - > > -#include > > -#include > > -#include > > -#include > > - > > -#include "DUart.h" > > - > > -STATIC CONST UINT32 mInvalidControlBits =3D > (EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE | \ > > - EFI_SERIAL_DATA_TERMINAL_RE= ADY); > > - > > -/** > > - Assert or deassert the control signals on a serial port. > > - The following control signals are set according their bit settings : > > - . Request to Send > > - . Data Terminal Ready > > - > > - @param[in] Control The following bits are taken into account : > > - . EFI_SERIAL_REQUEST_TO_SEND : assert/deasse= rt the > > - "Request To Send" control signal if this b= it is > > - equal to one/zero. > > - . EFI_SERIAL_DATA_TERMINAL_READY : assert/de= assert > > - the "Data Terminal Ready" control signal i= f this > > - bit is equal to one/zero. > > - . EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE : enab= le/disable > > - the hardware loopback if this bit is equal= to > > - one/zero. > > - . EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE : not = supported. > > - . EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE : = enable/ > > - disable the hardware flow control based on= CTS (Clear > > - To Send) and RTS (Ready To Send) control s= ignals. > > - > > - @retval EFI_SUCCESS The new control bits were set on the devic= e. > > - @retval EFI_UNSUPPORTED The device does not support this operation= . > > - > > -**/ > > -EFI_STATUS > > -EFIAPI > > -SerialPortSetControl ( > > - IN UINT32 Control > > - ) > > -{ > > - UINT32 McrBits; > > - UINTN UartBase; > > - > > - UartBase =3D (UINTN)PcdGet64 (PcdSerialRegisterBase); > > - > > - if (Control & (mInvalidControlBits)) { > > - return EFI_UNSUPPORTED; > > - } > > - > > - McrBits =3D MmioRead8 (UartBase + UMCR); > > - > > - if (Control & EFI_SERIAL_REQUEST_TO_SEND) { > > - McrBits |=3D DUART_MCR_RTS; > > - } else { > > - McrBits &=3D ~DUART_MCR_RTS; > > - } > > - > > - if (Control & EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE) { > > - McrBits |=3D DUART_MCR_LOOP; > > - } else { > > - McrBits &=3D ~DUART_MCR_LOOP; > > - } > > - > > - if (Control & EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) { > > - McrBits |=3D DUART_MCR_AFE; > > - } else { > > - McrBits &=3D ~DUART_MCR_AFE; > > - } > > - > > - MmioWrite32 (UartBase + UMCR, McrBits); > > - > > - return EFI_SUCCESS; > > -} > > - > > -/** > > - Retrieve the status of the control bits on a serial device. > > - > > - @param[out] Control Status of the control bits on a serial devi= ce : > > - > > - . EFI_SERIAL_DATA_CLEAR_TO_SEND, > > - EFI_SERIAL_DATA_SET_READY, > > - EFI_SERIAL_RING_INDICATE, > > - EFI_SERIAL_CARRIER_DETECT, > > - EFI_SERIAL_REQUEST_TO_SEND, > > - EFI_SERIAL_DATA_TERMINAL_READY > > - are all related to the DTE (Data Terminal E= quipment) > > - and DCE (Data Communication Equipment) mode= s of > > - operation of the serial device. > > - . EFI_SERIAL_INPUT_BUFFER_EMPTY : equal to on= e if the > > - receive buffer is empty, 0 otherwise. > > - . EFI_SERIAL_OUTPUT_BUFFER_EMPTY : equal to o= ne if the > > - transmit buffer is empty, 0 otherwise. > > - . EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE : equal= to one if > > - the hardware loopback is enabled (the ouput= feeds the > > - receive buffer), 0 otherwise. > > - . EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE : equal= to one if > > - a loopback is accomplished by software, 0 o= therwise. > > - . EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE : e= qual to > > - one if the hardware flow control based on C= TS (Clear > > - To Send) and RTS (Ready To Send) control si= gnals is > > - enabled, 0 otherwise. > > - > > - @retval EFI_SUCCESS The control bits were read from the serial = device. > > - > > -**/ > > -EFI_STATUS > > -EFIAPI > > -SerialPortGetControl ( > > - OUT UINT32 *Control > > - ) > > -{ > > - UINT32 MsrRegister; > > - UINT32 McrRegister; > > - UINT32 LsrRegister; > > - UINTN UartBase; > > - > > - UartBase =3D (UINTN)PcdGet64 (PcdSerialRegisterBase); > > - > > - MsrRegister =3D MmioRead8 (UartBase + UMSR); > > - McrRegister =3D MmioRead8 (UartBase + UMCR); > > - LsrRegister =3D MmioRead8 (UartBase + ULSR); > > - > > - *Control =3D 0; > > - > > - if ((MsrRegister & DUART_MSR_CTS) =3D=3D DUART_MSR_CTS) { > > - *Control |=3D EFI_SERIAL_CLEAR_TO_SEND; > > - } > > - > > - if ((McrRegister & DUART_MCR_RTS) =3D=3D DUART_MCR_RTS) { > > - *Control |=3D EFI_SERIAL_REQUEST_TO_SEND; > > - } > > - > > - if ((LsrRegister & DUART_LSR_TEMT) =3D=3D DUART_LSR_TEMT) { > > - *Control |=3D EFI_SERIAL_OUTPUT_BUFFER_EMPTY; > > - } > > - > > - if ((McrRegister & DUART_MCR_AFE) =3D=3D DUART_MCR_AFE) { > > - *Control |=3D EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE; > > - } > > - > > - if ((McrRegister & DUART_MCR_LOOP) =3D=3D DUART_MCR_LOOP) { > > - *Control |=3D EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE; > > - } > > - > > - return EFI_SUCCESS; > > -} > > - > > -/* > > - * Return Baud divisor on basis of Baudrate > > - */ > > -UINT32 > > -CalculateBaudDivisor ( > > - IN UINT64 BaudRate > > - ) > > -{ > > - UINTN DUartClk; > > - UINTN FreqSystemBus; > > - > > - FreqSystemBus =3D GetBusFrequency (); > > - DUartClk =3D FreqSystemBus/PcdGet32(PcdPlatformFreqDiv); > > - > > - return ((DUartClk)/(BaudRate * 16)); > > -} > > - > > -/* > > - Initialise the serial port to the specified settings. > > - All unspecified settings will be set to the default values. > > - > > - @return Always return EFI_SUCCESS or EFI_INVALID_PARAMETER. > > - > > - **/ > > -VOID > > -EFIAPI > > -DuartInitializePort ( > > - IN UINT64 BaudRate > > - ) > > -{ > > - UINTN UartBase; > > - UINT32 BaudDivisor; > > - > > - UartBase =3D (UINTN)PcdGet64 (PcdSerialRegisterBase); > > - BaudDivisor =3D CalculateBaudDivisor (BaudRate); > > - > > - > > - while (!(MmioRead8 (UartBase + ULSR) & DUART_LSR_TEMT)); > > - > > - // > > - // Enable and assert interrupt when new data is available on > > - // external device, > > - // setup data format, setup baud divisor > > - // > > - MmioWrite8 (UartBase + UIER, 0x1); > > - MmioWrite8 (UartBase + ULCR, DUART_LCR_BKSE | DUART_LCRVAL); > > - MmioWrite8 (UartBase + UDLB, 0); > > - MmioWrite8 (UartBase + UDMB, 0); > > - MmioWrite8 (UartBase + ULCR, DUART_LCRVAL); > > - MmioWrite8 (UartBase + UMCR, DUART_MCRVAL); > > - MmioWrite8 (UartBase + UFCR, DUART_FCRVAL); > > - MmioWrite8 (UartBase + ULCR, DUART_LCR_BKSE | DUART_LCRVAL); > > - MmioWrite8 (UartBase + UDLB, BaudDivisor & 0xff); > > - MmioWrite8 (UartBase + UDMB, (BaudDivisor >> 8) & 0xff); > > - MmioWrite8 (UartBase + ULCR, DUART_LCRVAL); > > - > > - return; > > -} > > - > > -/** > > - Programmed hardware of Serial port. > > - > > - @return Always return EFI_SUCCESS. > > - > > -**/ > > -EFI_STATUS > > -EFIAPI > > -SerialPortInitialize ( > > - VOID > > - ) > > -{ > > - UINT64 BaudRate; > > - BaudRate =3D (UINTN)PcdGet64 (PcdUartDefaultBaudRate); > > - > > - > > - DuartInitializePort (BaudRate); > > - > > - return EFI_SUCCESS; > > -} > > - > > -/** > > - Write data to serial device. > > - > > - @param Buffer Point of data buffer which need to be writt= en. > > - @param NumberOfBytes Number of output bytes which are cached in > Buffer. > > - > > - @retval 0 Write data failed. > > - @retval !0 Actual number of bytes written to serial de= vice. > > - > > -**/ > > -UINTN > > -EFIAPI > > -SerialPortWrite ( > > - IN UINT8 *Buffer, > > - IN UINTN NumberOfBytes > > - ) > > -{ > > - UINT8 *Final; > > - UINTN UartBase; > > - > > - Final =3D &Buffer[NumberOfBytes]; > > - UartBase =3D (UINTN)PcdGet64 (PcdSerialRegisterBase); > > - > > - while (Buffer < Final) { > > - while ((MmioRead8 (UartBase + ULSR) & DUART_LSR_THRE) =3D=3D 0); > > - MmioWrite8 (UartBase + UTHR, *Buffer++); > > - } > > - > > - return NumberOfBytes; > > -} > > - > > -/** > > - Read data from serial device and save the data in buffer. > > - > > - @param Buffer Point of data buffer which need to be writt= en. > > - @param NumberOfBytes Number of output bytes which are cached in > Buffer. > > - > > - @retval 0 Read data failed. > > - @retval !0 Actual number of bytes read from serial dev= ice. > > - > > -**/ > > -UINTN > > -EFIAPI > > -SerialPortRead ( > > - OUT UINT8 *Buffer, > > - IN UINTN NumberOfBytes > > - ) > > -{ > > - UINTN Count; > > - UINTN UartBase; > > - > > - UartBase =3D (UINTN)PcdGet64 (PcdSerialRegisterBase); > > - > > - for (Count =3D 0; Count < NumberOfBytes; Count++, Buffer++) { > > - // Loop while waiting for a new char(s) to arrive in the > > - // RxFIFO > > - while ((MmioRead8 (UartBase + ULSR) & DUART_LSR_DR) =3D=3D 0); > > - > > - *Buffer =3D MmioRead8 (UartBase + URBR); > > - } > > - > > - return NumberOfBytes; > > -} > > - > > -/** > > - Check to see if any data is available to be read from the debug devi= ce. > > - > > - @retval EFI_SUCCESS At least one byte of data is available to = be read > > - @retval EFI_NOT_READY No data is available to be read > > - @retval EFI_DEVICE_ERROR The serial device is not functioning prope= rly > > - > > -**/ > > -BOOLEAN > > -EFIAPI > > -SerialPortPoll ( > > - VOID > > - ) > > -{ > > - UINTN UartBase; > > - > > - UartBase =3D (UINTN)PcdGet64 (PcdSerialRegisterBase); > > - > > - return ((MmioRead8 (UartBase + ULSR) & DUART_LSR_DR) !=3D 0); > > -} > > - > > -/** > > - Set new attributes to LS1043a. > > - > > - @param BaudRate The baud rate of the serial device. = If the baud > rate is not supported, > > - the speed will be reduced down to th= e nearest supported > one and the > > - variable's value will be updated acc= ordingly. > > - @param ReceiveFifoDepth The number of characters the device = will > buffer on input. If the specified > > - value is not supported, the variable= 's value will be reduced > down to the > > - nearest supported one. > > - @param Timeout If applicable, the number of microse= conds the > device will wait > > - before timing out a Read or a Write = operation. > > - @param Parity If applicable, this is the EFI_PARIT= Y_TYPE that is > computed or checked > > - as each character is transmitted or = received. If the device > does not > > - support parity, the value is the def= ault parity value. > > - @param DataBits The number of data bits in each char= acter > > - @param StopBits If applicable, the EFI_STOP_BITS_TYP= E number of > stop bits per character. > > - If the device does not support stop = bits, the value is the > default stop > > - bit value. > > - > > - @retval EFI_SUCCESS All attributes were set correctly on= the serial > device. > > - > > -**/ > > -EFI_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 > > - ) > > -{ > > - DuartInitializePort (*BaudRate); > > - > > - return EFI_SUCCESS; > > -} > > diff --git a/Silicon/NXP/Library/DUartPortLib/DUartPortLib.inf > b/Silicon/NXP/Library/DUartPortLib/DUartPortLib.inf > > deleted file mode 100644 > > index 7a2fa619b0..0000000000 > > --- a/Silicon/NXP/Library/DUartPortLib/DUartPortLib.inf > > +++ /dev/null > > @@ -1,34 +0,0 @@ > > -# DUartPortLib.inf > > -# > > -# Component description file for DUartPortLib module > > -# > > -# Copyright (c) 2013, Freescale Ltd. All rights reserved. > > -# Copyright 2017 NXP > > -# > > -# SPDX-License-Identifier: BSD-2-Clause-Patent > > -# > > - > > -[Defines] > > - INF_VERSION =3D 0x0001001A > > - BASE_NAME =3D DUartPortLib > > - FILE_GUID =3D c42dfe79-8de5-429e-a055-2d0a58591= 498 > > - MODULE_TYPE =3D BASE > > - VERSION_STRING =3D 1.0 > > - LIBRARY_CLASS =3D SerialPortLib > > - > > -[Sources.common] > > - DUartPortLib.c > > - > > -[LibraryClasses] > > - PcdLib > > - SocLib > > - > > -[Packages] > > - MdeModulePkg/MdeModulePkg.dec > > - MdePkg/MdePkg.dec > > - Silicon/NXP/NxpQoriqLs.dec > > - > > -[Pcd] > > - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase > > - gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate > > - gNxpQoriqLsTokenSpaceGuid.PcdPlatformFreqDiv > > -- > > 2.17.1 > >