From owner-freebsd-hackers@freebsd.org Sat Nov 25 18:19:37 2017 Return-Path: Delivered-To: freebsd-hackers@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id A35EFDEC97F for ; Sat, 25 Nov 2017 18:19:37 +0000 (UTC) (envelope-from harald.boehm@fau.de) Received: from mx-rz-3.rrze.uni-erlangen.de (mx-rz-3.rrze.uni-erlangen.de [IPv6:2001:638:a000:1025::16]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 555E468C79 for ; Sat, 25 Nov 2017 18:19:36 +0000 (UTC) (envelope-from harald.boehm@fau.de) Received: from mx-rz-3.rrze.uni-erlangen.de (mx-rz-3.rrze.uni-erlangen.de [IPv6:2001:638:a000:1025::16]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx-rz-3.rrze.uni-erlangen.de (Postfix) with ESMTPS id 3ykhCx4QvRz24K7 for ; Sat, 25 Nov 2017 19:19:25 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fau.de; s=fau-2013; t=1511633965; bh=eb90e/q3eqxUc0x9ROEkCQhyumoIEtP7DivyYmrvgaY=; h=Subject:To:References:From:Date:In-Reply-To:From:To:CC:Subject; b=OnCoKiZUR0Y+rj1u99ErsWlxrE/APSYmknPszn+TPZtbemL4Y4Orm2D+epiS+96PO hxSDP/S2atG4jbT2UfzbwBG+xR068wR+jWgbQBj6p0ZCF8oMV0d+AbSQshJXFo0tiY vH8MH4e32QW64xWwQQdjnbo9RKjosZ2dFwCF4bg156gJTevlmRpPRmewG5OqNfUJwj AOtg8QWz0M/wLPZ8hNPRqTI5huuyQcopd3N2VhH9nlommaKayQbAGaRPOH/toTOhki HGuxmJsfGY3qmFm4hyo9+aF1x4HBlicQvRNbYflqxUxxUTgnfY3norLclUKKMmX8xd DaK7tRVt/DkAQ== X-Virus-Scanned: amavisd-new at boeck4.rrze.uni-erlangen.de (RRZE) X-RRZE-Flag: Not-Spam X-RRZE-Submit-IP: 2.205.196.29 Received: from [192.168.2.100] (ip-2-205-196-29.web.vodafone.de [2.205.196.29]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: U2FsdGVkX19O7f68OC7FLm3VSJjlIYZa9wNbnBPoSeE=) by smtp-auth.uni-erlangen.de (Postfix) with ESMTPSA id 3ykhCr5gLdz24JL for ; Sat, 25 Nov 2017 19:19:20 +0100 (CET) Subject: Re: ACPICA missing support for device I/O port ranges To: freebsd-hackers@freebsd.org References: <2497671.hb7Q7Esj6H@ralph.baldwin.cx> From: =?UTF-8?Q?Harald_B=c3=b6hm?= Message-ID: Date: Sat, 25 Nov 2017 19:19:19 +0100 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:52.0) Gecko/20100101 Thunderbird/52.4.0 MIME-Version: 1.0 In-Reply-To: <2497671.hb7Q7Esj6H@ralph.baldwin.cx> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 25 Nov 2017 18:19:37 -0000 > IO ranges are not supposed to be in _CRS. An IO range is used for relocatable > resources and would be in _PRS to say "you can use I/O ports at addresses, A, > B, or C". Specifically, the "Range" of an I/O port is the range of the > starting addresses. Normal I/O addresses in _CRS are set to a fixed range > with the same values for Range Min and Range Max. For example: > > IO (Decode16, > 0x0CF8, // Range Minimum > 0x0CF8, // Range Maximum > 0x01, // Alignment > 0x08, // Length > ) > > This says it uses the '8' (Length) I/O ports starting at 0xcf8 and that they > are fixed at 0xcf8 because the starting address has to be >= 0xcf8 (range min) > and <= 0xcf8 (range max). The _CRS blob from your dump says that it wants to > allocate 255 I/O ports with a starting address of 0x700, 0x701, 0x702, 0x703, > .... , 0x7fd, 0x7fe, or 0x7ff, but it doesn't tell us _which_ of those ranges > it is actually using (e.g. is it using 0x700 -> 0x7ff or is it using 0x780 -> > 0x88f, etc.). Thanks for the explanation, after reading it and having a look at the ACPI spec everyhing makes much more sense now. :) > Probably it's just a bug in your BIOS and it means to use > 0x700 -> 0x7ff and the BIOS author doesn't understand what Range Maximum means. > It is not the end address of the full I/O port addresses reserved, but the > maximum starting address (I agree this is a bit odd, but this is what the > spec says). >From what I know about the device so far, this seems to be true. The device only uses I/O ports in the range between 0x700 and 0x7FF, that's why I was confused in the first place. It also seems to be the only device that has this buggy port description in my BIOS, all other device entries look like the example you gave. The affected Laptop is a MacBook Pro 11,3. The device should be present in Apple computers with two graphics cards, it is used to switch between GPUs. So, if anyone else is using a Mac with two graphics cards, it would be interesting to see, whether this bug is also present in other machines (acpidump -td and search for GMUX). > Assuming the BIOS is buggy, we can add a hack for iorange that adds the > resource if max == min + length and emit a warning under bootverbose about > the BIOS being buggy. > That would be great. Alternatively, I could read the _CRS in the driver's code directly. I already wrote a patch, adapting your idea, below is the output of diff -u, does this look reasonable? --- acpi_resource.c 2017-11-25 17:17:02.083043000 +0100 +++ acpi_resource.c.patch 2017-11-25 17:20:57.223232000 +0100 @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -525,7 +526,26 @@ if (cp == NULL) return; - device_printf(dev, "I/O range not supported\n"); + + /* + * The CRS is not supposed to contain io ranges for relocatable + * resources. If the resource's length is equal to the address + * range between low and high, it indicates that the BIOS author + * probably meant that the device uses I/O ports from low to + * high. Therefore, we set the resources here, so drivers are + * able allocate them correctly. + */ + if (high == (low+length)) { + if (boothowto & RB_VERBOSE) { + device_printf(dev, + "warning: Device's _CRS contains an invalid I/O port range\n"); + } + + bus_set_resource(dev, SYS_RES_IOPORT, cp->ar_nio++, low, + length); + } else { + device_printf(dev, "I/O range not supported\n"); + } } static void