From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=217.140.106.53; helo=cam-smtp0.cambridge.arm.com; envelope-from=sami.mujawar@arm.com; receiver=edk2-devel@lists.01.org Received: from cam-smtp0.cambridge.arm.com (unknown [217.140.106.53]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 2ADCB21959CB2 for ; Fri, 21 Dec 2018 09:00:39 -0800 (PST) Received: from E107187.Arm.com (e107187.arm.com [10.1.195.55]) by cam-smtp0.cambridge.arm.com (8.13.8/8.13.8) with ESMTP id wBLGvOUl018491; Fri, 21 Dec 2018 17:00:36 GMT From: Sami Mujawar To: edk2-devel@lists.01.org Cc: alexei.fedorov@arm.com, leif.lindholm@linaro.org, Matteo.Carlini@arm.com, Stephanie.Hughes-Fitt@arm.com, nd@arm.com Date: Fri, 21 Dec 2018 16:57:16 +0000 Message-Id: <20181221165719.49480-20-sami.mujawar@arm.com> X-Mailer: git-send-email 2.11.0.windows.3 In-Reply-To: <20181221165719.49480-1-sami.mujawar@arm.com> References: <20181221165719.49480-1-sami.mujawar@arm.com> Subject: [PATCH v1 19/22] DynamicTablesPkg: Arm SPCR Table Generator X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 X-List-Received-Date: Fri, 21 Dec 2018 17:00:40 -0000 The SPCR generator uses the configuration manager protocol to obtain the serial port information from the platform configuration manager. It then updates a template SPCR table structure. This table data is used by the Table Manager to install the SPCR table. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Sami Mujawar --- DynamicTablesPkg/DynamicTables.dsc.inc | 1 + DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf | 42 +++ DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c | 326 ++++++++++++++++++++ 3 files changed, 369 insertions(+) diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/DynamicTables.dsc.inc index 056a1293c93268a6203fc3711079880d11cbc1bc..cfefd57d451155880e6b0e62f1f0605160e6a9aa 100644 --- a/DynamicTablesPkg/DynamicTables.dsc.inc +++ b/DynamicTablesPkg/DynamicTables.dsc.inc @@ -31,6 +31,7 @@ [Components.common] NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/AcpiGtdtLibArm.inf NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm.inf NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf + NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf } # diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf new file mode 100644 index 0000000000000000000000000000000000000000..8dd94e550b8181dea13d5be81688cc35b8b80eac --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf @@ -0,0 +1,42 @@ +## @file +# SPCR Table Generator +# +# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +## + +[Defines] + INF_VERSION = 0x00010019 + BASE_NAME = AcpiSpcrLibArm + FILE_GUID = 55088136-7B78-4974-B1EE-F630150D0DE7 + VERSION_STRING = 1.0 + MODULE_TYPE = DXE_DRIVER + LIBRARY_CLASS = NULL|DXE_DRIVER + CONSTRUCTOR = AcpiSpcrLibConstructor + DESTRUCTOR = AcpiSpcrLibDestructor + +[Sources] + SpcrGenerator.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + DynamicTablesPkg/DynamicTablesPkg.dec + +[LibraryClasses] + BaseLib + +[Pcd] + +[Protocols] + +[Guids] + diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c new file mode 100644 index 0000000000000000000000000000000000000000..52c7e475baf511c0abf1442113e88248c5d035b3 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c @@ -0,0 +1,326 @@ +/** @file + SPCR Table Generator + + Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + @par Reference(s): + - Microsoft Serial Port Console Redirection Table + Specification - Version 1.03 - August 10, 2015. + +**/ + +#include +#include +#include +#include +#include + +// Module specific include files. +#include +#include +#include +#include +#include + +/** ARM standard SPCR Table Generator + + Constructs the SPCR table for PL011 or SBSA UART peripherals. + +Requirements: + The following Configuration Manager Object(s) are required by + this Generator: + - EArmObjSerialConsolePortInfo + +NOTE: This implementation ignores the possibility that the Serial settings may + be modified from the UEFI Shell. A more complex handler would be needed + to (e.g.) recover serial port settings from the UART, or non-volatile + storage. +*/ + +#pragma pack(1) + +/** This macro defines the no flow control option. +*/ +#define SPCR_FLOW_CONTROL_NONE 0 + +/**A template for generating the SPCR Table. + + Note: fields marked "{Template}" will be updated dynamically. +*/ +STATIC +EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE AcpiSpcr = { + ACPI_HEADER ( + EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE, + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE, + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION + ), + 0, // {Template}: Serial Port Subtype + { + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE + }, + ARM_GAS32 (0), // {Template}: Serial Port Base Address + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERRUPT_TYPE_GIC, + 0, // Not used on ARM + 0, // {Template}: Serial Port Interrupt + 0, // {Template}: Serial Port Baudrate + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_PARITY_NO_PARITY, + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_STOP_BITS_1, + SPCR_FLOW_CONTROL_NONE, + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_TERMINAL_TYPE_ANSI, + EFI_ACPI_RESERVED_BYTE, + 0xFFFF, + 0xFFFF, + 0x00, + 0x00, + 0x00, + 0x00000000, + 0x00, + EFI_ACPI_RESERVED_DWORD +}; + +#pragma pack() + +/** This macro expands to a function that retrieves the Serial + Port Information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArm, + EArmObjSerialConsolePortInfo, + CM_ARM_SERIAL_PORT_INFO + ) + +/** Construct the SPCR ACPI table. + + This function invokes the Configuration Manager protocol interface + to get the required hardware information for generating the ACPI + table. + + If this function allocates any resources then they must be freed + in the FreeXXXXTableResources function. + + @param [in] This Pointer to the table generator. + @param [in] AcpiTableInfo Pointer to the ACPI Table Info. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [out] Table Pointer to the constructed ACPI Table. + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object was not found. + @retval EFI_UNSUPPORTED An unsupported baudrate was specified by the + Configuration Manager. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for the + requested object. +**/ +STATIC +EFI_STATUS +EFIAPI +BuildSpcrTable ( + IN CONST ACPI_TABLE_GENERATOR * CONST This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol, + OUT EFI_ACPI_DESCRIPTION_HEADER ** CONST Table + ) +{ + EFI_STATUS Status; + CM_ARM_SERIAL_PORT_INFO * SerialPortInfo; + + ASSERT (This != NULL); + ASSERT (AcpiTableInfo != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (Table != NULL); + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); + + *Table = NULL; + + Status = GetEArmObjSerialConsolePortInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &SerialPortInfo, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SPCR: Failed to get serial port information. Status = %r\n", + Status + )); + goto error_handler; + } + + if (SerialPortInfo->BaseAddress == 0) { + Status = EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: SPCR: Uart port base address is invalid. BaseAddress = 0x%lx\n", + SerialPortInfo->BaseAddress + )); + goto error_handler; + } + + if ((SerialPortInfo->PortSubtype != + EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_PL011_UART) && + (SerialPortInfo->PortSubtype != + EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART_2X) && + (SerialPortInfo->PortSubtype != + EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART) && + (SerialPortInfo->PortSubtype != + EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_DCC)) { + Status = EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: SPCR: Uart port sybtype is invalid. PortSubtype = 0x%x\n", + SerialPortInfo->PortSubtype + )); + goto error_handler; + } + + DEBUG ((DEBUG_INFO, "SPCR UART Configuration:\n")); + DEBUG ((DEBUG_INFO, " UART Base = 0x%lx\n", SerialPortInfo->BaseAddress)); + DEBUG ((DEBUG_INFO, " Clock = %d\n", SerialPortInfo->Clock)); + DEBUG ((DEBUG_INFO, " Baudrate = %ld\n", SerialPortInfo->BaudRate)); + DEBUG ((DEBUG_INFO, " Interrupt = %d\n", SerialPortInfo->Interrupt)); + + Status = AddAcpiHeader ( + CfgMgrProtocol, + This, + (EFI_ACPI_DESCRIPTION_HEADER*)&AcpiSpcr, + sizeof (EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE) + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SPCR: Failed to add ACPI header. Status = %r\n", + Status + )); + goto error_handler; + } + + // Update the serial port subtype + AcpiSpcr.InterfaceType = SerialPortInfo->PortSubtype; + + // Update the base address + AcpiSpcr.BaseAddress.Address = SerialPortInfo->BaseAddress; + + // Update the UART interrupt + AcpiSpcr.GlobalSystemInterrupt = SerialPortInfo->Interrupt; + + switch (SerialPortInfo->BaudRate) { + case 9600: + AcpiSpcr.BaudRate = + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_9600; + break; + case 19200: + AcpiSpcr.BaudRate = + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_19200; + break; + case 57600: + AcpiSpcr.BaudRate = + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_57600; + break; + case 115200: + AcpiSpcr.BaudRate = + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_115200; + break; + default: + Status = EFI_UNSUPPORTED; + DEBUG (( + DEBUG_ERROR, + "ERROR: SPCR: Invalid Baud Rate %ld, Status = %r\n", + SerialPortInfo->BaudRate, + Status + )); + goto error_handler; + } // switch + + *Table = (EFI_ACPI_DESCRIPTION_HEADER*)&AcpiSpcr; + +error_handler: + return Status; +} + +/** This macro defines the SPCR Table Generator revision. +*/ +#define SPCR_GENERATOR_REVISION CREATE_REVISION (1, 0) + +/** The interface for the SPCR Table Generator. +*/ +STATIC +CONST +ACPI_TABLE_GENERATOR SpcrGenerator = { + // Generator ID + CREATE_STD_ACPI_TABLE_GEN_ID (ESTD_ACPI_TABLE_ID_SPCR), + // Generator Description + L"ACPI.STD.SPCR.GENERATOR", + // ACPI Table Signature + EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE, + // ACPI Table Revision + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION, + // Creator ID + TABLE_GENERATOR_CREATOR_ID_ARM, + // Creator Revision + SPCR_GENERATOR_REVISION, + // Build Table function + BuildSpcrTable, + // No additional resources are allocated by the generator. + // Hence the Free Resource function is not required. + NULL +}; + +/** Register the Generator with the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is registered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_ALREADY_STARTED The Generator for the Table ID + is already registered. +**/ +EFI_STATUS +EFIAPI +AcpiSpcrLibConstructor ( + IN CONST EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE * CONST SystemTable + ) +{ + EFI_STATUS Status; + Status = RegisterAcpiTableGenerator (&SpcrGenerator); + DEBUG ((DEBUG_INFO, "SPCR: Register Generator. Status = %r\n", Status)); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** Deregister the Generator from the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is deregistered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The Generator is not registered. +**/ +EFI_STATUS +EFIAPI +AcpiSpcrLibDestructor ( + IN CONST EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE * CONST SystemTable + ) +{ + EFI_STATUS Status; + Status = DeregisterAcpiTableGenerator (&SpcrGenerator); + DEBUG ((DEBUG_INFO, "SPCR: Deregister Generator. Status = %r\n", Status)); + ASSERT_EFI_ERROR (Status); + return Status; +} -- 'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'