From e7ba0b7371b6a5d044a575fc92eb504d2a62c6a9 Mon Sep 17 00:00:00 2001 From: Christian Helmuth Date: Fri, 7 Oct 2022 17:10:05 +0200 Subject: [PATCH] pci: initialize BAR config on demand only On-demand initialization prevents read-write operations on BARs of invalid devices at construction time, which may result in surprising behavior later on, for example, when resetting X260 notebooks via ACPI information. --- repos/os/include/pci/config.h | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/repos/os/include/pci/config.h b/repos/os/include/pci/config.h index 2c5115ac72..ba2496ceac 100644 --- a/repos/os/include/pci/config.h +++ b/repos/os/include/pci/config.h @@ -104,34 +104,43 @@ struct Pci::Config : Genode::Mmio struct Upper_bits : Register<0x4, 32> { }; - Bar_32bit::access_t _conf { 0 }; + Bar_32bit::access_t _conf_value { 0 }; - Base_address(Genode::addr_t base) : Mmio(base) + Bar_32bit::access_t _conf() { - Bar_32bit::access_t v = read(); - write(0xffffffff); - _conf = read(); - write(v); + /* + * Initialize _conf_value on demand only to prevent read-write + * operations on BARs of invalid devices at construction time. + */ + if (!_conf_value) { + Bar_32bit::access_t v = read(); + write(0xffffffff); + _conf_value = read(); + write(v); + } + return _conf_value; } - bool valid() { return _conf != 0; } + Base_address(Genode::addr_t base) : Mmio(base) { } + + bool valid() { return _conf() != 0; } bool memory() { - return !Bar_32bit::Memory_space_indicator::get(_conf); } + return !Bar_32bit::Memory_space_indicator::get(_conf()); } bool bit64() { - return Bar_32bit::Memory_type::get(_conf) == + return Bar_32bit::Memory_type::get(_conf()) == Bar_32bit::Memory_type::SIZE_64BIT; } bool prefetchable() { - return Bar_32bit::Memory_prefetchable::get(_conf); } + return Bar_32bit::Memory_prefetchable::get(_conf()); } Genode::size_t size() { - return 1 + (memory() ? ~Bar_32bit::Memory_base::masked(_conf) - : ~Bar_32bit::Io_base::masked(_conf)); + return 1 + (memory() ? ~Bar_32bit::Memory_base::masked(_conf()) + : ~Bar_32bit::Io_base::masked(_conf())); } Genode::uint64_t addr()