Workaround fixed I/O port resources encoded as I/O port ranges in _CRS.

ACPI I/O port descriptors use _MIN and _MAX fields to specify the set
of allowable base (start) addresses for an I/O port resource along with
a _LEN field specifying the length.  A fixed resource is supposed to be
encoded with _MIN == _MAX, but some buggy firmwares instead set _MAX to
the end of the fixed range.  Relocating I/O ranges only make sense in
_PRS (possible resource settings), not in _CRS (current resource settings),
so if an I/O port range with _MAX set set to the end of the range is
present in _CRS, treat it as a fixed I/O port resource starting at
_MIN.

PR:		224096
Submitted by:	Harald Böhm <harald@boehm.codes>
Pointy hat to:	jhb (taking so long to actually commit this)
MFC after:	1 week
This commit is contained in:
John Baldwin 2018-04-18 18:36:26 +00:00
parent 6d83b2e971
commit eb33d8ce3e

View File

@ -530,6 +530,24 @@ acpi_res_set_iorange(device_t dev, void *context, uint64_t low,
if (cp == NULL)
return;
/*
* XXX: Some BIOSes contain buggy _CRS entries where fixed I/O
* ranges have the maximum base address (_MAX) to the end of the
* I/O range instead of the start. These are then treated as a
* relocatable I/O range rather than a fixed I/O resource. As a
* workaround, treat I/O resources encoded this way as fixed I/O
* ports.
*/
if (high == (low + length)) {
if (bootverbose)
device_printf(dev,
"_CRS has fixed I/O port range defined as relocatable\n");
bus_set_resource(dev, SYS_RES_IOPORT, cp->ar_nio++, low, length);
return;
}
device_printf(dev, "I/O range not supported\n");
}