From patchwork Tue Nov 20 21:52:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andy Shevchenko X-Patchwork-Id: 1000751 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.intel.com Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 42zzyP2Br7z9s3q for ; Wed, 21 Nov 2018 08:54:53 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 00C36C2211C; Tue, 20 Nov 2018 21:54:20 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 367B9C22163; Tue, 20 Nov 2018 21:53:07 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 537B8C21FCE; Tue, 20 Nov 2018 21:52:53 +0000 (UTC) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by lists.denx.de (Postfix) with ESMTPS id 2FC29C22197 for ; Tue, 20 Nov 2018 21:52:49 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Nov 2018 13:52:47 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,258,1539673200"; d="scan'208";a="101849298" Received: from black.fi.intel.com ([10.237.72.28]) by orsmga003.jf.intel.com with ESMTP; 20 Nov 2018 13:52:44 -0800 Received: by black.fi.intel.com (Postfix, from userid 1003) id E7CF416AB; Tue, 20 Nov 2018 23:52:39 +0200 (EET) From: Andy Shevchenko To: Simon Glass , Bin Meng , Lokesh Vutla , Alexander Graf , Christophe Leroy , u-boot@lists.denx.de, Patrice Chotard Date: Tue, 20 Nov 2018 23:52:38 +0200 Message-Id: <20181120215238.21551-8-andriy.shevchenko@linux.intel.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181120215238.21551-1-andriy.shevchenko@linux.intel.com> References: <20181120215238.21551-1-andriy.shevchenko@linux.intel.com> MIME-Version: 1.0 Cc: Andy Shevchenko Subject: [U-Boot] [PATCH v3 7/7] x86: acpi: Generate SPCR table X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Microsoft specifies a SPCR (Serial Port Console Redirection Table) [1]. Let's provide it in U-Boot. [1]: https://docs.microsoft.com/en-us/windows-hardware/drivers/serports/serial-port-console-redirection-table Signed-off-by: Andy Shevchenko Reviewed-by: Simon Glass Reviewed-by: Simon Glass --- arch/x86/include/asm/acpi_table.h | 2 + arch/x86/lib/acpi_table.c | 118 ++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) diff --git a/arch/x86/include/asm/acpi_table.h b/arch/x86/include/asm/acpi_table.h index 51cc806673..e3b65cff66 100644 --- a/arch/x86/include/asm/acpi_table.h +++ b/arch/x86/include/asm/acpi_table.h @@ -327,6 +327,8 @@ struct acpi_global_nvs; #define ACPI_DBG2_USB_XHCI 0x0000 #define ACPI_DBG2_USB_EHCI 0x0001 +#define ACPI_DBG2_UNKNOWN 0x00FF + /* SPCR (Serial Port Console Redirection table) */ struct __packed acpi_spcr { struct acpi_table_header header; diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c index c6b2026613..5a37a22c8c 100644 --- a/arch/x86/lib/acpi_table.c +++ b/arch/x86/lib/acpi_table.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -338,6 +339,115 @@ static void acpi_create_mcfg(struct acpi_mcfg *mcfg) header->checksum = table_compute_checksum((void *)mcfg, header->length); } +static void acpi_create_spcr(struct acpi_spcr *spcr) +{ + struct acpi_table_header *header = &(spcr->header); + struct serial_device_info serial_info = {0}; + ulong serial_address, serial_offset; + uint serial_config; + uint serial_width; + int access_size; + int space_id; + int ret; + + /* Fill out header fields */ + acpi_fill_header(header, "SPCR"); + header->length = sizeof(struct acpi_spcr); + header->revision = 2; + + ret = serial_getinfo(&serial_info); + if (ret) + serial_info.type = SERIAL_CHIP_UNKNOWN; + + /* Encode chip type */ + switch (serial_info.type) { + case SERIAL_CHIP_16550_COMPATIBLE: + spcr->interface_type = ACPI_DBG2_16550_COMPATIBLE; + break; + case SERIAL_CHIP_UNKNOWN: + default: + spcr->interface_type = ACPI_DBG2_UNKNOWN; + break; + } + + /* Encode address space */ + switch (serial_info.addr_space) { + case SERIAL_ADDRESS_SPACE_MEMORY: + space_id = ACPI_ADDRESS_SPACE_MEMORY; + break; + case SERIAL_ADDRESS_SPACE_IO: + default: + space_id = ACPI_ADDRESS_SPACE_IO; + break; + } + + serial_width = serial_info.reg_width * 8; + serial_offset = serial_info.reg_offset << serial_info.reg_shift; + serial_address = serial_info.addr + serial_offset; + + /* Encode register access size */ + switch (serial_info.reg_shift) { + case 0: + access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS; + break; + case 1: + access_size = ACPI_ACCESS_SIZE_WORD_ACCESS; + break; + case 2: + access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS; + break; + case 3: + access_size = ACPI_ACCESS_SIZE_QWORD_ACCESS; + break; + default: + access_size = ACPI_ACCESS_SIZE_UNDEFINED; + break; + } + + debug("UART type %u @ %lx\n", spcr->interface_type, serial_address); + + /* Fill GAS */ + spcr->serial_port.space_id = space_id; + spcr->serial_port.bit_width = serial_width; + spcr->serial_port.bit_offset = 0; + spcr->serial_port.access_size = access_size; + spcr->serial_port.addrl = lower_32_bits(serial_address); + spcr->serial_port.addrh = upper_32_bits(serial_address); + + /* Encode baud rate */ + switch (serial_info.baudrate) { + case 9600: + spcr->baud_rate = 3; + break; + case 19200: + spcr->baud_rate = 4; + break; + case 57600: + spcr->baud_rate = 6; + break; + case 115200: + spcr->baud_rate = 7; + break; + default: + spcr->baud_rate = 0; + break; + } + + ret = serial_getconfig(&serial_config); + if (ret) + serial_config = SERIAL_DEFAULT_CONFIG; + + spcr->parity = SERIAL_GET_PARITY(serial_config); + spcr->stop_bits = SERIAL_GET_STOP(serial_config); + + /* No PCI devices for now */ + spcr->pci_device_id = 0xffff; + spcr->pci_vendor_id = 0xffff; + + /* Fix checksum */ + header->checksum = table_compute_checksum((void *)spcr, header->length); +} + /* * QEMU's version of write_acpi_tables is defined in drivers/misc/qfw.c */ @@ -352,6 +462,7 @@ ulong write_acpi_tables(ulong start) struct acpi_fadt *fadt; struct acpi_mcfg *mcfg; struct acpi_madt *madt; + struct acpi_spcr *spcr; int i; current = start; @@ -440,6 +551,13 @@ ulong write_acpi_tables(ulong start) acpi_add_table(rsdp, mcfg); current = ALIGN(current, 16); + debug("ACPI: * SPCR\n"); + spcr = (struct acpi_spcr *)current; + acpi_create_spcr(spcr); + current += spcr->header.length; + acpi_add_table(rsdp, spcr); + current = ALIGN(current, 16); + debug("current = %x\n", current); acpi_rsdp_addr = (unsigned long)rsdp;