Date: Tue, 21 Nov 2017 15:38:30 -0800 From: John Baldwin <jhb@freebsd.org> To: freebsd-hackers@freebsd.org Cc: Harald =?ISO-8859-1?Q?B=F6hm?= <harald.boehm@fau.de> Subject: Re: ACPICA missing support for device I/O port ranges Message-ID: <2497671.hb7Q7Esj6H@ralph.baldwin.cx> In-Reply-To: <e8699d73-f38b-3825-67ef-8d8f973e4ce0@fau.de> References: <e8699d73-f38b-3825-67ef-8d8f973e4ce0@fau.de>
next in thread | previous in thread | raw e-mail | index | archive | help
On Saturday, November 18, 2017 06:52:54 PM Harald B=F6hm wrote: > Hi all, >=20 > I've been working on a device driver lately and was having trouble > allocating its resources using bus_alloc_resource_any(), although its= > I/O ports can be read from its _CRS. >=20 > This is the output of acpidump -td: >=20 > Device (GMUX) > { > ... > Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settin= gs > { > IO (Decode16, > 0x0700, // Range Minimum > 0x07FF, // Range Maximum > 0x01, // Alignment > 0xFF, // Length > ) > }) > ... > } >=20 > After digging into the code in /sys/dev/acpica/acpi_resources.c I was= > able to find the problem. The function acpi_res_set_iorange(), which > seems to be responsible for calling bus_set_resource() is just a > function stub that prints a message that I/O ranges are not supported= . >=20 > static void > acpi_res_set_iorange(device_t dev, void *context, uint64_t low, > =09=09 uint64_t high, uint64_t length, uint64_t align) > { > struct acpi_res_context=09*cp =3D (struct acpi_res_context *)cont= ext; >=20 > if (cp =3D=3D NULL) > =09return; > device_printf(dev, "I/O range not supported\n"); > } >=20 > After adding a call to bus_set_resource() to that function, I was abl= e > to allocate the device's resources. >=20 > Does anyone know, why the function has not been implemented or why I/= O > ranges are not supported? IO ranges are not supposed to be in _CRS. An IO range is used for relo= catable resources and would be in _PRS to say "you can use I/O ports at address= es, 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 ra= nge 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 >=3D 0xcf8 (r= ange min) and <=3D 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 0x= 780 -> 0x88f, etc.). Probably it's just a bug in your BIOS and it means to us= e 0x700 -> 0x7ff and the BIOS author doesn't understand what Range Maximu= m 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 t= he spec says). Assuming the BIOS is buggy, we can add a hack for iorange that adds the= resource if max =3D=3D min + length and emit a warning under bootverbos= e about the BIOS being buggy. --=20 John Baldwin
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?2497671.hb7Q7Esj6H>