From owner-svn-src-all@freebsd.org Thu Oct 22 17:31:42 2020 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 649B844E000; Thu, 22 Oct 2020 17:31:42 +0000 (UTC) (envelope-from mw@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4CHDtk23lWz4CVN; Thu, 22 Oct 2020 17:31:42 +0000 (UTC) (envelope-from mw@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 10D481A2C7; Thu, 22 Oct 2020 17:31:42 +0000 (UTC) (envelope-from mw@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 09MHVfGD042501; Thu, 22 Oct 2020 17:31:41 GMT (envelope-from mw@FreeBSD.org) Received: (from mw@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 09MHVfau042500; Thu, 22 Oct 2020 17:31:41 GMT (envelope-from mw@FreeBSD.org) Message-Id: <202010221731.09MHVfau042500@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mw set sender to mw@FreeBSD.org using -f From: Marcin Wojtas Date: Thu, 22 Oct 2020 17:31:41 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r366942 - stable/12/sys/dev/uart X-SVN-Group: stable-12 X-SVN-Commit-Author: mw X-SVN-Commit-Paths: stable/12/sys/dev/uart X-SVN-Commit-Revision: 366942 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 22 Oct 2020 17:31:42 -0000 Author: mw Date: Thu Oct 22 17:31:41 2020 New Revision: 366942 URL: https://svnweb.freebsd.org/changeset/base/366942 Log: MFC r362574 Fix AccessWidth and BitWidth parsing in SPCR table The ACPI Specification defines a Generic Address Structure (GAS), which is used to describe UART controller register layout in the SPCR table. The driver responsible for parsing it (uart_cpu_acpi) wrongly associates the Access Size field to the uart_bas's regshft and the register BitWidth to the regiowidth - according to the definitions it should be opposite. This problem remained hidden most likely because the majority of platforms use 32-bit registers (BitWidth) which are accessed with the according size (Dword). However on Marvell Armada 8k / Cn913x platforms, the 32-bit registers should be accessed with Byte granulity, which unveiled the issue. This patch fixes above by proper values assignment and slightly improved parsing. Note that handling of the AccessWidth set to EFI_ACPI_6_0_UNDEFINED is needed to work around a buggy SPCR table on EC2 x86 "bare metal" instances. Reviewed by: manu, imp, cperciva, greg_unrelenting.technology Obtained from: Semihalf Modified: stable/12/sys/dev/uart/uart_cpu_acpi.c Modified: stable/12/sys/dev/uart/uart_cpu_acpi.c ============================================================================== --- stable/12/sys/dev/uart/uart_cpu_acpi.c Thu Oct 22 17:05:55 2020 (r366941) +++ stable/12/sys/dev/uart/uart_cpu_acpi.c Thu Oct 22 17:31:41 2020 (r366942) @@ -120,11 +120,46 @@ uart_cpu_acpi_spcr(int devtype, struct uart_devinfo *d (int)spcr->SerialPort.SpaceId); goto out; } - if (spcr->SerialPort.AccessWidth == 0) + switch (spcr->SerialPort.AccessWidth) { + case 0: /* EFI_ACPI_6_0_UNDEFINED */ + /* FALLTHROUGH */ + case 1: /* EFI_ACPI_6_0_BYTE */ + di->bas.regiowidth = 1; + break; + case 2: /* EFI_ACPI_6_0_WORD */ + di->bas.regiowidth = 2; + break; + case 3: /* EFI_ACPI_6_0_DWORD */ + di->bas.regiowidth = 4; + break; + case 4: /* EFI_ACPI_6_0_QWORD */ + di->bas.regiowidth = 8; + break; + default: + printf("UART unsupported access width: %d!\n", + (int)spcr->SerialPort.AccessWidth); + goto out; + } + switch (spcr->SerialPort.BitWidth) { + case 0: + /* FALLTHROUGH */ + case 8: di->bas.regshft = 0; - else - di->bas.regshft = spcr->SerialPort.AccessWidth - 1; - di->bas.regiowidth = spcr->SerialPort.BitWidth / 8; + break; + case 16: + di->bas.regshft = 1; + break; + case 32: + di->bas.regshft = 2; + break; + case 64: + di->bas.regshft = 3; + break; + default: + printf("UART unsupported bit width: %d!\n", + (int)spcr->SerialPort.BitWidth); + goto out; + } switch (spcr->BaudRate) { case 0: /* Special value; means "keep current value unchanged". */