lx_kit: map I/O mem with proper offset

In case multiple devices shared the same memory-mapped I/O page
we have to take the offset into account. This commit fixes the
'pc_usb_host_drv' on the Thinkpad X201 where the two EHCI host
controller share the some I/O memory page.

Fixes #4477.
This commit is contained in:
Josef Söntgen 2022-04-20 15:23:54 +02:00 committed by Christian Helmuth
parent 396cc53020
commit 2fd2b7d628
2 changed files with 19 additions and 10 deletions

View File

@ -122,8 +122,7 @@ void * Device::io_mem_local_addr(addr_t phys_addr, size_t size)
if (!io.io_mem.constructed())
io.io_mem.construct(*_pdev, io.idx);
ret = (void*)((addr_t)io.io_mem->local_addr<void>()
+ (phys_addr - io.addr));
ret = (void*)((addr_t)io.io_mem->local_addr<void>() + phys_addr - io.addr);
});
return ret;
}

View File

@ -103,15 +103,22 @@ static Str create_device_node(Xml_generator &xml,
bool const memory = r.type() == R::MEMORY;
xml.node(memory ? "io_mem" : "io_port", [&] () {
xml.attribute("phys_addr",
to_string(Hex(memory ? mmio_phys_addr : r.bar())));
xml.attribute("size", to_string(Hex(r.size())));
xml.attribute("bar", id);
});
if (memory) {
xml.node("io_mem", [&] () {
xml.attribute("phys_addr", to_string(Hex(mmio_phys_addr)));
xml.attribute("size", to_string(Hex(r.size())));
xml.attribute("bar", id);
});
if (memory)
mmio_phys_addr += align_addr(r.size(), 12);
} else {
xml.node("io_port", [&] () {
xml.attribute("phys_addr", to_string(Hex(r.bar())));
xml.attribute("size", to_string(Hex(r.size())));
xml.attribute("bar", id);
});
}
});
});
@ -439,6 +446,9 @@ void *Platform::Device::Mmio::_local_addr()
if (device.resource(phys_bar_id).prefetchable())
cache = Cache::WRITE_COMBINED;
auto const r = device.resource(phys_bar_id);
Range::start = (r.base() & 0xfffu);
}
Io_mem_session_capability io_mem_cap =
@ -450,7 +460,7 @@ void *Platform::Device::Mmio::_local_addr()
io_mem_client.dataspace());
}
return _attached_ds->local_addr<void*>();
return (void*)(_attached_ds->local_addr<char>() + Range::start);
}