pcib(4): Write window registers after resource adjustment

When adjusting resources we should write updated window base/limit into
the registers.  Without this newly added address range won't be routed
through the bridge properly.

Use MIN()/MAX() against current window base/limit to not shrink it on
the other side if the window is shared by several resources.

Align passed resource start/end to the set window granularity to keep
it properly aligned.  Currently this is mostly called by other bridges
having the same window alignment, but it may be change one day.

Reviewed by:	jrtc27, jhb
MFC after:	1 week
Sponsored by:	iXsystems, Inc.
Differential Revision: 	https://reviews.freebsd.org/D31693
This commit is contained in:
Alexander Motin 2021-08-26 20:21:56 -04:00
parent d396c67f26
commit 15cb3b5404

View File

@ -2345,6 +2345,7 @@ pcib_adjust_resource(device_t bus, device_t child, int type, struct resource *r,
{
struct pcib_softc *sc;
struct pcib_window *w;
rman_res_t wmask;
int error;
sc = device_get_softc(bus);
@ -2375,9 +2376,18 @@ pcib_adjust_resource(device_t bus, device_t child, int type, struct resource *r,
* then we need to expand the window.
*/
if (start < w->base || end > w->limit) {
error = pcib_expand_window(sc, w, type, start, end);
wmask = ((rman_res_t)1 << w->step) - 1;
error = pcib_expand_window(sc, w, type,
MIN(start & ~wmask, w->base),
MAX(end | wmask, w->limit));
if (error != 0)
return (error);
if (bootverbose)
device_printf(sc->dev,
"grew %s window to %#jx-%#jx\n",
w->name, (uintmax_t)w->base,
(uintmax_t)w->limit);
pcib_write_windows(sc, w->mask);
}
}