From nobody Fri May 3 06:24:42 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+53508+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+53508+1787277+3901457@groups.io Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1580232013250108.16670785278518; Tue, 28 Jan 2020 09:20:13 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id e1Q4YY1788612xitCtMlmQz5; Tue, 28 Jan 2020 09:20:12 -0800 X-Received: from mail-wm1-f68.google.com (mail-wm1-f68.google.com [209.85.128.68]) by mx.groups.io with SMTP id smtpd.web10.243.1580232011417247620 for ; Tue, 28 Jan 2020 09:20:11 -0800 X-Received: by mail-wm1-f68.google.com with SMTP id m10so2258943wmc.0 for ; Tue, 28 Jan 2020 09:20:11 -0800 (PST) X-Gm-Message-State: 9jVUPP9PWHwtqc3p349Fboiyx1787277AA= X-Google-Smtp-Source: APXvYqwJb6wtbzyBYqZHOYyM60b9XknFTK+MdIwtufvgppYBnhH4UNxI2loraK1okDURcyiDSPEzOw== X-Received: by 2002:a1c:770e:: with SMTP id t14mr6136418wmi.101.1580232009702; Tue, 28 Jan 2020 09:20:09 -0800 (PST) X-Received: from localhost.localdomain ([84.203.49.247]) by smtp.gmail.com with ESMTPSA id 205sm4000853wmd.42.2020.01.28.09.20.08 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 28 Jan 2020 09:20:09 -0800 (PST) From: "Pete Batard" To: devel@edk2.groups.io Cc: ard.biesheuvel@linaro.org, leif@nuviainc.com, philmd@redhat.com Subject: [edk2-devel] [edk2-platforms][PATCH 1/4] Silicon/Broadcom/Bcm283x: Add clock manager constants Date: Tue, 28 Jan 2020 17:19:53 +0000 Message-Id: <20200128171956.9680-2-pete@akeo.ie> In-Reply-To: <20200128171956.9680-1-pete@akeo.ie> References: <20200128171956.9680-1-pete@akeo.ie> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,pete@akeo.ie Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1580232012; bh=L1EVqwtoSBFmgYxW9c+jfiVvMRSfDGbKqtuZztkhbS8=; h=Cc:Date:From:Reply-To:Subject:To; b=oZxI4ZbJcIJktpDwfbH7Y04WWYGTzxvgO+feOfZmkRFj8Jg1lsV4imc0f57Hpaocmih 8aAS5jXfkL+1U1ZpXcE54BOl0UBzfrPGHzqUqeXi4mDSkioCZ9IpRhU3CcfWL8xoHbFAy HbkPjhNLoiUKGehXya9xjiDoXP0HT7xma6I= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" We need these to be able to read the VPU divisor to set the 16650 serial baudrate on the Raspberry Pi. Signed-off-by: Pete Batard Reviewed-by: Ard Biesheuvel --- Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836.h | 22 +++++++++= +++++++++++ 1 file changed, 22 insertions(+) diff --git a/Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836.h b/= Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836.h index dd9a698f7218..7ba4877337a8 100644 --- a/Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836.h +++ b/Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836.h @@ -31,6 +31,28 @@ #define BCM2836_WDOG_RSTC_WRCFG_MASK 0x00000030 #define BCM2836_WDOG_RSTC_WRCFG_FULL_RESET 0x00000020 =20 +/* clock manager constants */ +#define BCM2836_CM_OFFSET 0x00101000 +#define BCM2836_CM_BASE (BCM2836_SOC_R= EGISTERS + BCM2836_CM_OFFSET) +#define BCM2836_CM_GEN_CLOCK_CONTROL 0x0000 +#define BCM2836_CM_GEN_CLOCK_DIVISOR 0x0004 +#define BCM2836_CM_VPU_CLOCK_CONTROL 0x0008 +#define BCM2836_CM_VPU_CLOCK_DIVISOR 0x000c +#define BCM2836_CM_SYSTEM_CLOCK_CONTROL 0x0010 +#define BCM2836_CM_SYSTEM_CLOCK_DIVISOR 0x0014 +#define BCM2836_CM_H264_CLOCK_CONTROL 0x0028 +#define BCM2836_CM_H264_CLOCK_DIVISOR 0x002c +#define BCM2836_CM_PWM_CLOCK_CONTROL 0x00a0 +#define BCM2836_CM_PWM_CLOCK_DIVISOR 0x00a4 +#define BCM2836_CM_UART_CLOCK_CONTROL 0x00f0 +#define BCM2836_CM_UART_CLOCK_DIVISOR 0x00f4 +#define BCM2836_CM_SDC_CLOCK_CONTROL 0x01a8 +#define BCM2836_CM_SDC_CLOCK_DIVISOR 0x01ac +#define BCM2836_CM_ARM_CLOCK_CONTROL 0x01b0 +#define BCM2836_CM_ARM_CLOCK_DIVISOR 0x01b4 +#define BCM2836_CM_EMMC_CLOCK_CONTROL 0x01c0 +#define BCM2836_CM_EMMC_CLOCK_DIVISOR 0x01c4 + /* mailbox interface constants */ #define BCM2836_MBOX_OFFSET 0x0000b880 #define BCM2836_MBOX_BASE_ADDRESS (BCM2836_SOC_R= EGISTERS + BCM2836_MBOX_OFFSET) --=20 2.21.0.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#53508): https://edk2.groups.io/g/devel/message/53508 Mute This Topic: https://groups.io/mt/70222626/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Fri May 3 06:24:42 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+53509+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+53509+1787277+3901457@groups.io Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1580232018742717.5416947103504; Tue, 28 Jan 2020 09:20:18 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id EM2PYY1788612xQDTArhhVcQ; Tue, 28 Jan 2020 09:20:17 -0800 X-Received: from mail-wr1-f51.google.com (mail-wr1-f51.google.com [209.85.221.51]) by mx.groups.io with SMTP id smtpd.web12.237.1580232016287864699 for ; Tue, 28 Jan 2020 09:20:16 -0800 X-Received: by mail-wr1-f51.google.com with SMTP id y17so16971777wrh.5 for ; Tue, 28 Jan 2020 09:20:16 -0800 (PST) X-Gm-Message-State: 7y7nXZKTGeDt2bWQH9wbBsflx1787277AA= X-Google-Smtp-Source: APXvYqzvoK6dpk5RZWC8zuhXzJw2Dxy9AeVlWYYmzf5VYeDVIwakDaAyjxOeeKROguiK85fXMEDkFQ== X-Received: by 2002:adf:a141:: with SMTP id r1mr27511243wrr.285.1580232013645; Tue, 28 Jan 2020 09:20:13 -0800 (PST) X-Received: from localhost.localdomain ([84.203.49.247]) by smtp.gmail.com with ESMTPSA id 205sm4000853wmd.42.2020.01.28.09.20.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 28 Jan 2020 09:20:13 -0800 (PST) From: "Pete Batard" To: devel@edk2.groups.io Cc: ard.biesheuvel@linaro.org, leif@nuviainc.com, philmd@redhat.com Subject: [edk2-devel] [edk2-platforms][PATCH 2/4] Platform/RPi: Add serial lib for runtime PL011 vs miniUART detection Date: Tue, 28 Jan 2020 17:19:54 +0000 Message-Id: <20200128171956.9680-3-pete@akeo.ie> In-Reply-To: <20200128171956.9680-1-pete@akeo.ie> References: <20200128171956.9680-1-pete@akeo.ie> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,pete@akeo.ie Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1580232017; bh=6+osYkv4OCk6cQ5RbAxGPXyERlWesKJ5pISXWC+pzl0=; h=Cc:Date:From:Reply-To:Subject:To; b=w8Ouh2oQL9JP3kndSgJqt0z2LqnbrDiyxBwSADiHVAqtvKoH+VG0F40KIzqSWAR7tjr 4qYetPR0mmz607hpVy3wD3ZfpeHapem1uIsrwpPBDoEYcMBxWUK1CLHjfoUSlJlwiIiCS r0wm0Z9u4hGVHFYIF7Qd6hckhu5CuFK+h3k= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" The Raspberry Pi platform contains two UARTs, one PL011-based and the other (called miniUART) 16650-compatible, that are pinmuxed to the GPIO serial port according to whether a Device Tree overlay is present in config.txt or not. In most cases, it takes only the user commenting or uncommenting an overlay line in config.txt to switch between PL011 and miniUART. As such, the use of a build time option to select the UART should be avoided when it is effectively possible to detect which of the UART is in use at runtime, through a simple MMIO call. This patch does just this by adding a new DualSerialPortLib that directs the SerialPortLib implementation to use either 16650 or PL011 according to the GPIO pinmuxing. It should be noted that this code mostly a merge of * MdeModulePkg/Library/BaseSerialPortLib16550 * ArmPlatformPkg/Library/PL011SerialPortLib with non-relevant elements stripped from BaseSerialPortLib16550 (such as PCI support) and a new call added to retreive the 16650 baudrate divisor, since it is dependent on the platform's VPU's clock divisor. Signed-off-by: Pete Batard Reviewed-by: Ard Biesheuvel --- Platform/RaspberryPi/Library/DualSerialPortLib/DualSerialPortLib.c | 836= ++++++++++++++++++++ Platform/RaspberryPi/Library/DualSerialPortLib/DualSerialPortLib.inf | 55= ++ 2 files changed, 891 insertions(+) diff --git a/Platform/RaspberryPi/Library/DualSerialPortLib/DualSerialPortL= ib.c b/Platform/RaspberryPi/Library/DualSerialPortLib/DualSerialPortLib.c new file mode 100644 index 000000000000..05e12f383785 --- /dev/null +++ b/Platform/RaspberryPi/Library/DualSerialPortLib/DualSerialPortLib.c @@ -0,0 +1,836 @@ +/** @file + 16550 and PL011 Serial Port library functions for Raspberry Pi + + Copyright (c) 2020, Pete Batard + Copyright (c) 2018, AMD Incorporated. All rights reserved.
+ Copyright (c) 2014, Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2012 - 2016, ARM Ltd. All rights reserved.
+ Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.
+ Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +BOOLEAN UsePl011Uart =3D FALSE; +BOOLEAN UsePl011UartSet =3D FALSE; + +#define PL011_UART_REGISTER_BASE BCM2836_PL011_UART_BASE_ADDRESS +#define MINI_UART_REGISTER_BASE (BCM2836_MINI_UART_BASE_ADDRESS + 0x= 40) + +// +// 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 + +/** + Read an 8-bit 16550 register. + + @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. + + @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 by Of= fset. + + @return The value written to the 16550 register. + +**/ +UINT8 +SerialPortWriteRegister ( + UINTN Base, + UINTN Offset, + UINT8 Value + ) +{ + return MmioWrite8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride), V= alue); +} + +/** + 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. Transmit + // + return (BOOLEAN) ((SerialPortReadRegister (SerialRegisterBase, R_UAR= T_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. Transmit + // 0 1 No cable connected. Transmit + // 1 0 Cable connected, but not clear to send. Wait + // 1 1 Cable connected, and clar to send. Transmit + // + return (BOOLEAN) ((SerialPortReadRegister (SerialRegisterBase, R_UAR= T_MSR) & (B_UART_MSR_DSR | B_UART_MSR_CTS)) !=3D (B_UART_MSR_DSR)); + } + } + + return TRUE; +} + +/** + Return the baud generator divisor to use for 16650 setup. + + @param SerialBaudRate The desired baud rate. + + @return The baud generator divisor. +**/ +UINT32 +SerialPortGetDivisor ( + UINT32 SerialBaudRate +) +{ + UINT64 BaseClockRate; + UINT32 Divisor; + + // + // On the Raspberry Pi, the clock to use for the 16650-compatible UART + // is the base clock divided by the 12.12 fixed point VPU clock divisor. + // + BaseClockRate =3D (UINT64)PcdGet32 (PcdSerialClockRate) * 4; + Divisor =3D MmioRead32(BCM2836_CM_BASE + BCM2836_CM_VPU_CLOCK_DIVISOR) &= 0xFFFFFF; + if (Divisor !=3D 0) + BaseClockRate =3D (BaseClockRate << 12) / Divisor; + + // + // Now calculate divisor for baud generator + // Ref_Clk_Rate / Baud_Rate / 16 + // + Divisor =3D (UINT32)BaseClockRate / (SerialBaudRate * 16); + if (((UINT32)BaseClockRate % (SerialBaudRate * 16)) >=3D SerialBaudRate = * 8) { + Divisor++; + } + return Divisor; +} + +/** + 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 + ) +{ + UINTN SerialRegisterBase; + UINT32 Divisor; + UINT32 CurrentDivisor; + BOOLEAN Initialized; + UINT64 BaudRate; + UINT32 ReceiveFifoDepth; + EFI_PARITY_TYPE Parity; + UINT8 DataBits; + EFI_STOP_BITS_TYPE StopBits; + + // + // First thing we need to do is determine which of PL011 or miniUART is = selected + // + if (!UsePl011UartSet) { + UsePl011Uart =3D ((MmioRead32(GPIO_BASE_ADDRESS + 4) & 0x0003F000) =3D= =3D 0x00024000); + UsePl011UartSet =3D TRUE; + } + + if (UsePl011Uart) { + BaudRate =3D FixedPcdGet64 (PcdUartDefaultBaudRate); + ReceiveFifoDepth =3D 0; // Use default FIFO depth + Parity =3D (EFI_PARITY_TYPE)FixedPcdGet8 (PcdUartDefaultParity); + DataBits =3D FixedPcdGet8 (PcdUartDefaultDataBits); + StopBits =3D (EFI_STOP_BITS_TYPE) FixedPcdGet8 (PcdUartDefaultStopBits= ); + + return PL011UartInitializePort ( + PL011_UART_REGISTER_BASE, + PL011UartClockGetFreq(), + &BaudRate, + &ReceiveFifoDepth, + &Parity, + &DataBits, + &StopBits + ); + } else { + SerialRegisterBase =3D MINI_UART_REGISTER_BASE; + Divisor =3D SerialPortGetDivisor (PcdGet32 (PcdSerialBaudRate)); + + // + // 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)(Seria= lPortReadRegister (SerialRegisterBase, R_UART_LCR) | B_UART_LCR_DLAB)); + CurrentDivisor =3D SerialPortReadRegister (SerialRegisterBase, R_UART= _BAUD_HIGH) << 8; + CurrentDivisor |=3D (UINT32) SerialPortReadRegister (SerialRegisterBas= e, R_UART_BAUD_LOW); + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8)(Seria= lPortReadRegister (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 empty. + // + while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & (B_U= ART_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_DL= AB); + SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_HIGH, (UINT8)= (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)(PcdGe= t8 (PcdSerialLineControl) & 0x3F)); + + // + // Enable and reset FIFOs + // Strip reserved bits from PcdSerialFifoControl + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, 0x00); + SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, (UINT8)(PcdGe= t8 (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 returned. + If the return value is less than NumberOfBytes, then the write operation= failed. + + If Buffer is NULL, then ASSERT(). + + If NumberOfBytes is zero, then return 0. + + @param Buffer Pointer to the data buffer to be written. + @param NumberOfBytes Number of bytes to written to the serial device. + + @retval 0 NumberOfBytes is 0. + @retval >0 The number of bytes written to the serial devic= e. + If this value is less than NumberOfBytes, then = the write operation failed. + +**/ +UINTN +EFIAPI +SerialPortWrite ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + UINTN SerialRegisterBase; + UINTN Result; + UINTN Index; + UINTN FifoSize; + + // + // Serial writes may happen *before* the UART has been initialized + // and if we use the wrong UART then, all kind of bad things happen. + // To alleviate this, we add UART detection in SerialPortWrite and + // guard the UART detection with a second boolean. + // + if (!UsePl011UartSet) { + UsePl011Uart =3D ((MmioRead32(GPIO_BASE_ADDRESS + 4) & 0x0003F000) =3D= =3D 0x00024000); + UsePl011UartSet =3D TRUE; + } + + if (UsePl011Uart) { + return PL011UartWrite (PL011_UART_REGISTER_BASE, Buffer, NumberOfBytes= ); + } else { + if (Buffer =3D=3D NULL) { + return 0; + } + + SerialRegisterBase =3D MINI_UART_REGISTER_BASE; + + 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_TXRD= Y)); + + // + // 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 trans= mit 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_TXRD= Y)); + + // + // 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, *Buffer= ); + } + } + return Result; + } +} + +/** + 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 SerialRegisterBase; + UINTN Result; + UINT8 Mcr; + + if (UsePl011Uart) { + return PL011UartRead (PL011_UART_REGISTER_BASE, Buffer, NumberOfBytes); + } else { + if (NULL =3D=3D Buffer) { + return 0; + } + + SerialRegisterBase =3D MINI_UART_REGISTER_BASE; + + Mcr =3D (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_MCR= ) & ~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, (UINT8)= (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_RXBUF= ); + } + + 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 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 SerialRegisterBase; + + if (UsePl011Uart) { + return PL011UartPoll (PL011_UART_REGISTER_BASE); + } else { + SerialRegisterBase =3D MINI_UART_REGISTER_BASE; + + // + // 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)(S= erialPortReadRegister (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)(Ser= ialPortReadRegister (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 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 SerialRegisterBase; + UINT8 Mcr; + + if (UsePl011Uart) { + return PL011UartSetControl (PL011_UART_REGISTER_BASE, Control); + } else { + // + // 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; + } + + SerialRegisterBase =3D MINI_UART_REGISTER_BASE; + + // + // 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_T= O_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 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 SerialRegisterBase; + UINT8 Msr; + UINT8 Mcr; + UINT8 Lsr; + + if (UsePl011Uart) { + return PL011UartGetControl (PL011_UART_REGISTER_BASE, Control); + } else { + SerialRegisterBase =3D MINI_UART_REGISTER_BASE; + + *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_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; + } + + return RETURN_SUCCESS; + } +} + +/** + Sets the baud rate, receive FIFO depth, transmit/receice time out, parit= y, + 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 SerialRegisterBase; + UINT32 SerialBaudRate; + UINTN Divisor; + UINT8 Lcr; + UINT8 LcrData; + UINT8 LcrParity; + UINT8 LcrStop; + + if (UsePl011Uart) { + return PL011UartInitializePort ( + PL011_UART_REGISTER_BASE, + PL011UartClockGetFreq(), + BaudRate, + ReceiveFifoDepth, + Parity, + DataBits, + StopBits + ); + } else { + SerialRegisterBase =3D MINI_UART_REGISTER_BASE; + + // + // 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; + } + } + + // + // Configure baud rate + // + Divisor =3D SerialPortGetDivisor (SerialBaudRate); + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, B_UART_LCR_DL= AB); + SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_HIGH, (UINT8)= (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) (Lcr = & 0x3F)); + + return RETURN_SUCCESS; + } +} diff --git a/Platform/RaspberryPi/Library/DualSerialPortLib/DualSerialPortL= ib.inf b/Platform/RaspberryPi/Library/DualSerialPortLib/DualSerialPortLib.i= nf new file mode 100644 index 000000000000..af1e6b026fe6 --- /dev/null +++ b/Platform/RaspberryPi/Library/DualSerialPortLib/DualSerialPortLib.inf @@ -0,0 +1,55 @@ +## @file +# +# SerialPortLib instance for both PL011 and 16550 UART. +# +# Copyright (c) 2020, Pete Batard +# Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x0001001A + BASE_NAME =3D DualSerialPortLib + FILE_GUID =3D FD3EB93E-B59E-42B7-ABA4-ADA4B988B095 + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D SerialPortLib + +[Packages] + ArmPlatformPkg/ArmPlatformPkg.dec + EmbeddedPkg/EmbeddedPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + Silicon/Broadcom/Bcm283x/Bcm283x.dec + +[LibraryClasses] + IoLib + PcdLib + PL011UartClockLib + PL011UartLib + +[Sources] + DualSerialPortLib.c + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterAccessWidth ## SOMET= IMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## CONSU= MES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl ## CONSU= MES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialDetectCable ## SOMET= IMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate ## CONSU= MES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialLineControl ## CONSU= MES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialFifoControl ## CONSU= MES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate ## CONSU= MES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialPciDeviceInfo ## CONSU= MES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialExtendedTxFifoSize ## CONSU= MES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride ## CONSU= MES + +[FixedPcd] + gArmPlatformTokenSpaceGuid.PL011UartClkInHz + gBcm283xTokenSpaceGuid.PcdBcm283xRegistersAddress + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits --=20 2.21.0.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#53509): https://edk2.groups.io/g/devel/message/53509 Mute This Topic: https://groups.io/mt/70222629/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Fri May 3 06:24:42 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+53510+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+53510+1787277+3901457@groups.io Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1580232018846883.8159511948792; Tue, 28 Jan 2020 09:20:18 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id aeaRYY1788612xDNpTb79wk4; Tue, 28 Jan 2020 09:20:17 -0800 X-Received: from mail-wm1-f66.google.com (mail-wm1-f66.google.com [209.85.128.66]) by mx.groups.io with SMTP id smtpd.web12.238.1580232016736433548 for ; Tue, 28 Jan 2020 09:20:17 -0800 X-Received: by mail-wm1-f66.google.com with SMTP id p17so3460318wma.1 for ; Tue, 28 Jan 2020 09:20:16 -0800 (PST) X-Gm-Message-State: 4AqDkZkQJF9BKodeC3I9hedYx1787277AA= X-Google-Smtp-Source: APXvYqx0UXNkko0bVM5xP3yBwpYXKM90TGrl5G8F5VhTu6dmCgN19krfvxGgkaPVQWEIpjBo/EIjnA== X-Received: by 2002:a1c:1d09:: with SMTP id d9mr6422104wmd.91.1580232014993; Tue, 28 Jan 2020 09:20:14 -0800 (PST) X-Received: from localhost.localdomain ([84.203.49.247]) by smtp.gmail.com with ESMTPSA id 205sm4000853wmd.42.2020.01.28.09.20.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 28 Jan 2020 09:20:14 -0800 (PST) From: "Pete Batard" To: devel@edk2.groups.io Cc: ard.biesheuvel@linaro.org, leif@nuviainc.com, philmd@redhat.com Subject: [edk2-devel] [edk2-platforms][PATCH 3/4] Platform/RPi3: Enable the use of DualSerialPortLib Date: Tue, 28 Jan 2020 17:19:55 +0000 Message-Id: <20200128171956.9680-4-pete@akeo.ie> In-Reply-To: <20200128171956.9680-1-pete@akeo.ie> References: <20200128171956.9680-1-pete@akeo.ie> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,pete@akeo.ie Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1580232017; bh=Ou/1KPUTt/CwHMO0campa/nHK3tg6N8yxWnE79MyBGY=; h=Cc:Date:From:Reply-To:Subject:To; b=H1fUjcz/p7zjuTQwrV843bw/IEs3WbI5RTYYlAgK9pd2WcNY73llELhnJ2zqlE3EIjs UGcJvY39OZ4fZXVcGdAYet1dxU3AlF2CYyS8kjUHVELjCcWwXkxA3KI48wcc9/RSJYOsD Vu64kvIbmete1KPaZix9lNWtSjtj6IXHMXk= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" Note that, for the time being, the TF-A binary only outputs to the miniUART, but work is underway to add runtime UART detection to TF-A, after which we will use such a binary. Also note that this patch currently enforces the use of miniUART in the ACPI tables, as we have to pick one until we can switch to using DynamicTablesPkg/ConfigurationManagerDxe for ACPI generation. Signed-off-by: Pete Batard Reviewed-by: Ard Biesheuvel --- Platform/RaspberryPi/RPi3/RPi3.dsc | 15 +++++++++------ Platform/RaspberryPi/RPi3/Readme.md | 7 +++++++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/Platform/RaspberryPi/RPi3/RPi3.dsc b/Platform/RaspberryPi/RPi3= /RPi3.dsc index 2368b04f40a4..40fb0879c2ed 100644 --- a/Platform/RaspberryPi/RPi3/RPi3.dsc +++ b/Platform/RaspberryPi/RPi3/RPi3.dsc @@ -114,10 +114,10 @@ [LibraryClasses.common] ArmHvcLib|ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerPhyCounterLib/Ar= mGenericTimerPhyCounterLib.inf =20 - PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf - PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf - PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatfor= mHookLibNull.inf - SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPort= Lib16550.inf + # Dual serial port library + PL011UartClockLib|ArmPlatformPkg/Library/PL011UartClockLib/PL011UartCloc= kLib.inf + PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf + SerialPortLib|Platform/RaspberryPi/Library/DualSerialPortLib/DualSerialP= ortLib.inf =20 # Cryptographic libraries IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf @@ -379,14 +379,17 @@ [PcdsFixedAtBuild.common] # gBcm283xTokenSpaceGuid.PcdBcm283xRegistersAddress|0x3f000000 =20 - ## NS16550 compatible UART - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x3f215040 + # UARTs + gArmPlatformTokenSpaceGuid.PL011UartInteger|0 + gArmPlatformTokenSpaceGuid.PL011UartFractional|0 + gArmPlatformTokenSpaceGuid.PL011UartClkInHz|48000000 gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio|TRUE gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride|4 gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate|500000000 gEfiMdeModulePkgTokenSpaceGuid.PcdSerialFifoControl|0x27 gEfiMdeModulePkgTokenSpaceGuid.PcdSerialExtendedTxFifoSize|8 gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|115200 + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultReceiveFifoDepth|0 =20 ## Default Terminal Type ## 0-PCANSI, 1-VT100, 2-VT00+, 3-UTF8, 4-TTYTERM diff --git a/Platform/RaspberryPi/RPi3/Readme.md b/Platform/RaspberryPi/RPi= 3/Readme.md index 797da1bab4a9..58c0124ef75e 100644 --- a/Platform/RaspberryPi/RPi3/Readme.md +++ b/Platform/RaspberryPi/RPi3/Readme.md @@ -52,6 +52,13 @@ Build instructions from the top level edk2-platforms Rea= dme.md apply. armstub=3DRPI_EFI.fd disable_commandline_tags=3D1 ``` + Additionally, if you want to use PL011 instead of the miniUART, you can = add the lines: + ``` + device_tree_address=3D0x20000 + device_tree_end=3D0x30000 + device_tree=3Dbcm2710-rpi-3-b[-plus].dtb + dtoverlay=3Dminiuart-bt + ``` 5. Insert the uSD card and power up the Pi. =20 Note that if you have a model 3+ or a model 3 where you enabled USB boot t= hrough OTP --=20 2.21.0.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#53510): https://edk2.groups.io/g/devel/message/53510 Mute This Topic: https://groups.io/mt/70222631/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Fri May 3 06:24:42 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+53511+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+53511+1787277+3901457@groups.io Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1580232020856790.6643210835844; Tue, 28 Jan 2020 09:20:20 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id ZAtNYY1788612xpAyJ4n7HCl; Tue, 28 Jan 2020 09:20:19 -0800 X-Received: from mail-wr1-f42.google.com (mail-wr1-f42.google.com [209.85.221.42]) by mx.groups.io with SMTP id smtpd.web09.245.1580232018852493702 for ; Tue, 28 Jan 2020 09:20:19 -0800 X-Received: by mail-wr1-f42.google.com with SMTP id d16so16964660wre.10 for ; Tue, 28 Jan 2020 09:20:18 -0800 (PST) X-Gm-Message-State: fqNs2vpScsFwAEYUUCUWpvqPx1787277AA= X-Google-Smtp-Source: APXvYqzz87WJuQWEwRhcWvfcOI6BXYmwGT83IYD3jr7pIhwyldemIOI1Eb4XB17ULfEGStjuCeuLOw== X-Received: by 2002:a05:6000:11c9:: with SMTP id i9mr31202688wrx.164.1580232017038; Tue, 28 Jan 2020 09:20:17 -0800 (PST) X-Received: from localhost.localdomain ([84.203.49.247]) by smtp.gmail.com with ESMTPSA id 205sm4000853wmd.42.2020.01.28.09.20.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 28 Jan 2020 09:20:16 -0800 (PST) From: "Pete Batard" To: devel@edk2.groups.io Cc: ard.biesheuvel@linaro.org, leif@nuviainc.com, philmd@redhat.com Subject: [edk2-devel] [edk2-platforms][PATCH 4/4] Platform/RPi4: Enable the use of DualSerialPortLib Date: Tue, 28 Jan 2020 17:19:56 +0000 Message-Id: <20200128171956.9680-5-pete@akeo.ie> In-Reply-To: <20200128171956.9680-1-pete@akeo.ie> References: <20200128171956.9680-1-pete@akeo.ie> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,pete@akeo.ie Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1580232019; bh=xl56bb0TJNAUax/7mg5QuNKStvp2n5wmdo0GXLCpAuM=; h=Cc:Date:From:Reply-To:Subject:To; b=XAbTnLdoKZxaJhQ0Q9O6aWNrFsWedy5hDLtPYbQJRwywYf97jhYkTEK6e+f2kV0VNRa MkeTf7zJXH+ZmwaM/WbPCQLi/lsZdjPptH8748DMLzbfEr12bTiUFLD8WHZwB8vk1BOm3 Ns8oDyyQppPujtAF2tSPDA7zBzDD4BaYGqo= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" With DualSerialPortLib available, we can remove the PL011_ENABLE option and use this library instead of being tied to selecting only one of PL011SerialPortLib or BaseSerialPortLib16550. Note that, for the time being, we choose to default to selecting the PL011 based TF-A binary, since we have to pick one and we expect that most usage of the firmware will be for a PL011 configuration (we of course validated that the only drawback of using PL011 with a miniUART configuration the loss of the 2 lines of serial debug output from TF-A on startup and that there was no other issue besides that), but work is underway to add runtime UART detection to TF-A, after which we will revert to using a single TF-A binary that supports both UARTs. Also note that this patch currently enforces the use of PL011 for the ACPI tables, as we also have to pick one until we can switch to using DynamicTablesPkg/ConfigurationManagerDxe for ACPI generation, which we should do in a future update, and which will enable us to update the ACPI tables at runtime according to the user-selected UART. Signed-off-by: Pete Batard Reviewed-by: Ard Biesheuvel --- Platform/RaspberryPi/RPi4/AcpiTables/AcpiTables.inf | 7 ++++++ Platform/RaspberryPi/RPi4/RPi4.dsc | 26 +++--------------= --- Platform/RaspberryPi/RPi4/RPi4.fdf | 4 --- Platform/RaspberryPi/RPi4/Readme.md | 21 ++++------------ 4 files changed, 15 insertions(+), 43 deletions(-) diff --git a/Platform/RaspberryPi/RPi4/AcpiTables/AcpiTables.inf b/Platform= /RaspberryPi/RPi4/AcpiTables/AcpiTables.inf index 5ce4c0b52b32..aa8f67dec95e 100644 --- a/Platform/RaspberryPi/RPi4/AcpiTables/AcpiTables.inf +++ b/Platform/RaspberryPi/RPi4/AcpiTables/AcpiTables.inf @@ -54,3 +54,10 @@ [FixedPcd] gBcm283xTokenSpaceGuid.PcdBcm283xRegistersAddress gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate gEmbeddedTokenSpaceGuid.PcdInterruptBaseAddress + +# The following is a stopgap solution to default to PL011 +# usage in ACPI (most common case), until we can switch +# to using DynamicTablesPkg/ConfigurationManagerDxe. +[BuildOptions] + GCC:*_*_*_ASLPP_FLAGS =3D -DPL011_ENABLE + GCC:*_*_*_ASLCC_FLAGS =3D -DPL011_ENABLE diff --git a/Platform/RaspberryPi/RPi4/RPi4.dsc b/Platform/RaspberryPi/RPi4= /RPi4.dsc index bd3800c1d653..7c1937672597 100644 --- a/Platform/RaspberryPi/RPi4/RPi4.dsc +++ b/Platform/RaspberryPi/RPi4/RPi4.dsc @@ -38,7 +38,6 @@ [Defines] DEFINE SECURE_BOOT_ENABLE =3D FALSE DEFINE INCLUDE_TFTP_COMMAND =3D FALSE DEFINE DEBUG_PRINT_ERROR_LEVEL =3D 0x8000004F - DEFINE PL011_ENABLE =3D FALSE DEFINE ACPI_BASIC_MODE_ENABLE =3D FALSE =20 ##########################################################################= ###### @@ -118,16 +117,10 @@ [LibraryClasses.common] ArmHvcLib|ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerPhyCounterLib/Ar= mGenericTimerPhyCounterLib.inf =20 -!if $(PL011_ENABLE) =3D=3D TRUE + # Dual serial port library PL011UartClockLib|ArmPlatformPkg/Library/PL011UartClockLib/PL011UartCloc= kLib.inf PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf - SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortL= ib.inf -!else - PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf - PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf - PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatfor= mHookLibNull.inf - SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPort= Lib16550.inf -!endif + SerialPortLib|Platform/RaspberryPi/Library/DualSerialPortLib/DualSerialP= ortLib.inf =20 # Cryptographic libraries IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf @@ -239,12 +232,6 @@ [BuildOptions] GCC:*_*_AARCH64_DLINK_FLAGS =3D -Wl,--fix-cortex-a53-843419 GCC:RELEASE_*_*_CC_FLAGS =3D -DMDEPKG_NDEBUG -DNDEBUG =20 -!if $(PL011_ENABLE) =3D=3D TRUE - GCC:*_*_*_CC_FLAGS =3D -DPL011_ENABLE - GCC:*_*_*_ASLPP_FLAGS =3D -DPL011_ENABLE - GCC:*_*_*_ASLCC_FLAGS =3D -DPL011_ENABLE -!endif - [BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER] GCC:*_*_AARCH64_DLINK_FLAGS =3D -z common-page-size=3D0x10000 =20 @@ -410,22 +397,15 @@ [PcdsFixedAtBuild.common] gBcm27xxTokenSpaceGuid.PcdBcm27xxPciBusMmioLen|0x3ffffff gBcm27xxTokenSpaceGuid.PcdBcm27xxPciCpuMmioAdr|0x600000000 =20 -!if $(PL011_ENABLE) =3D=3D TRUE - ## PL011 UART - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0xfe201000 + # UARTs gArmPlatformTokenSpaceGuid.PL011UartInteger|0 gArmPlatformTokenSpaceGuid.PL011UartFractional|0 gArmPlatformTokenSpaceGuid.PL011UartClkInHz|48000000 -!else - ## NS16550 compatible UART - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0xfe215040 gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio|TRUE gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride|4 gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate|500000000 gEfiMdeModulePkgTokenSpaceGuid.PcdSerialFifoControl|0x27 gEfiMdeModulePkgTokenSpaceGuid.PcdSerialExtendedTxFifoSize|8 -!endif - gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|115200 gEfiMdePkgTokenSpaceGuid.PcdUartDefaultReceiveFifoDepth|0 =20 diff --git a/Platform/RaspberryPi/RPi4/RPi4.fdf b/Platform/RaspberryPi/RPi4= /RPi4.fdf index db393d47bcea..52ae1e5b65cb 100644 --- a/Platform/RaspberryPi/RPi4/RPi4.fdf +++ b/Platform/RaspberryPi/RPi4/RPi4.fdf @@ -51,11 +51,7 @@ [FD.RPI_EFI] # ATF primary boot image # 0x00000000|0x00020000 -!if $(PL011_ENABLE) =3D=3D TRUE FILE =3D Platform/RaspberryPi/$(PLATFORM_NAME)/TrustedFirmware/bl31_pl011.= bin -!else -FILE =3D Platform/RaspberryPi/$(PLATFORM_NAME)/TrustedFirmware/bl31_miniua= rt.bin -!endif =20 # # DTB. diff --git a/Platform/RaspberryPi/RPi4/Readme.md b/Platform/RaspberryPi/RPi= 4/Readme.md index 74afc0f89451..758d0124a6cf 100644 --- a/Platform/RaspberryPi/RPi4/Readme.md +++ b/Platform/RaspberryPi/RPi4/Readme.md @@ -20,8 +20,8 @@ following __major__ limitations: missing/incomplete ACPI tables as well as other factors. For Linux, using the `ACPI_BASIC_MODE_ENABLE` build option may help. - Serial I/O from the OS may not work due to CPU throttling affecting the - miniUART baudrate. This can be worked around by using the `PL011_ENABLE` - compilation option. + miniUART baudrate. This can be worked around by using the PL011 UART + through the device tree overlays. =20 # Building =20 @@ -32,11 +32,6 @@ The following additional build options are also availabl= e: ACPI (by disabling the Device Tree driver altogether). This may be requi= red to boot Operating Systems such as Linux on account of the current PCIe/x= HCI limitations. -- `-D PL011_ENABLE=3D1`: Selects PL011 for the serial console instead of t= he - miniUART (default). This doesn't change the GPIO pinout for the UART but - can be useful if you find that the miniUART baud rate changes when the - OS throttles the CPU. Note that this requires one of `disable-bt.dtbo` or - `miniuart-bt.dtbo` overlays to have been applied (see below). =20 # Booting the firmware =20 @@ -48,27 +43,21 @@ The following additional build options are also availab= le: - `start4.elf` - `overlays/miniuart-bt.dbto` or `overlays/disable-bt.dtbo` (Optional) 4. Create a `config.txt` with the following content: - - For a firmware **without** the `PL011_ENABLE` build option: ``` arm_64bit=3D1 enable_uart=3D1 - core_freq=3D250 enable_gic=3D1 armstub=3DRPI_EFI.fd disable_commandline_tags=3D1 ``` - - For a firmware **with** the `PL011_ENABLE` build option: + Additionally, if you want to use PL011 instead of the miniUART, you ca= n add the lines: ``` - arm_64bit=3D1 - enable_gic=3D1 - armstub=3DRPI_EFI.fd - disable_commandline_tags=3D1 device_tree_address=3D0x20000 device_tree_end=3D0x30000 device_tree=3Dbcm2711-rpi-4-b.dtb dtoverlay=3Dminiuart-bt ``` - The above also requires `miniuart-bt.dbto` to have been copied into an= `overlays/` + Note that doing so requires `miniuart-bt.dbto` to have been copied int= o an `overlays/` directory on the uSD card. Alternatively, you may use `disable-bt` ins= tead of `miniuart-bt` if you don't require BlueTooth. 5. Insert the uSD card and power up the Pi. @@ -80,7 +69,7 @@ The following additional build options are also available: The TF-A binaries were compiled from a TF-A source over which 2 serial-out= put related patches were applied, the first one to fix the miniUART baud rate not bein= g properly set to 115200 bauds with recent versions of `start4.elf` and the second on= e to allow -swicthing between miniUART and PL011 at build time. +the use of the PL011 UART. =20 No other alterations to the official source have been applied. =20 --=20 2.21.0.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#53511): https://edk2.groups.io/g/devel/message/53511 Mute This Topic: https://groups.io/mt/70222632/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-