From 5528434fb64afe95fe6e6c3fb3baa56cbbc7349c Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Fri, 29 Jul 2022 17:31:20 +0200 Subject: [PATCH] lx_kit & lx_emul: use generic platform API * Remove wrapper for legacy x86 platform API * Move PCI configuration space quirks to corresponding driver (pc_usb_host_drv, pc_wifi_drv, pc_intel_fb_drv) * Adapt driver test run-scripts to changed configuration Ref genodelabs/genode#4578 --- .../lib/import/import-lx_emul_common.inc | 6 - .../src/drivers/usb_host/spec/x86/target.inc | 1 - repos/dde_linux/src/include/lx_emul/pci.h | 56 ++ .../src/include/lx_emul/pci_config_space.h | 28 - repos/dde_linux/src/include/lx_kit/device.h | 88 ++- .../x86/lx_kit/platform_session/connection.h | 87 --- .../spec/x86/lx_kit/platform_session/device.h | 181 ------ repos/dde_linux/src/lib/lx_emul/pci.cc | 104 ++++ repos/dde_linux/src/lib/lx_emul/pci_bus.c | 199 ++++++ .../src/lib/lx_emul/pci_config_space.cc | 82 --- repos/dde_linux/src/lib/lx_emul/pci_init.cc | 46 -- .../lx_emul/shadow/drivers/pci/host-bridge.c | 11 + .../lx_emul/shadow/drivers/pci/pci-sysfs.c | 34 + .../src/lib/lx_emul/shadow/drivers/pci/pci.c | 36 ++ .../lib/lx_emul/shadow/drivers/pci/search.c | 44 ++ .../lx_emul/shadow/drivers/pci/setup-irq.c | 24 + .../lx_emul/shadow/drivers/pci/setup-res.c | 11 + .../dde_linux/src/lib/lx_emul/spec/x86/pci.c | 194 ------ repos/dde_linux/src/lib/lx_kit/device.cc | 78 ++- .../src/lib/lx_kit/spec/x86/platform.cc | 581 ------------------ repos/pc/lib/import/import-pc_lx_emul.mk | 11 +- repos/pc/lib/mk/wifi.inc | 1 - repos/pc/recipes/api/pc_linux/content.mk | 4 + .../recipes/pkg/test_usb_host_drv-pc/archives | 1 + .../raw/test_usb_host_drv-pc/drivers.config | 58 +- repos/pc/run/intel_fb.run | 93 ++- repos/pc/run/wifi.run | 82 ++- .../drivers/framebuffer/intel/pc/dummies.c | 30 + .../src/drivers/framebuffer/intel/pc/emul.cc | 19 + .../framebuffer/intel/pc/generated_dummies.c | 92 +-- .../drivers/framebuffer/intel/pc/lx_emul.h | 13 +- .../src/drivers/framebuffer/intel/pc/misc.cc | 20 - .../framebuffer/intel/pc/opregion_io_mem.cc | 11 +- .../pc/src/drivers/framebuffer/intel/pc/pci.c | 140 +++++ .../intel/pc/spec/x86_32/source.list | 14 - .../intel/pc/spec/x86_64/source.list | 14 - .../drivers/framebuffer/intel/pc/target.inc | 6 +- repos/pc/src/drivers/usb_host/pc/dummies.c | 8 + .../drivers/usb_host/pc/generated_dummies.c | 104 +--- repos/pc/src/drivers/usb_host/pc/lx_emul.c | 73 +++ repos/pc/src/drivers/usb_host/pc/lx_emul.h | 2 - .../usb_host/pc/spec/x86_32/source.list | 13 - .../usb_host/pc/spec/x86_64/source.list | 13 - repos/pc/src/drivers/usb_host/pc/target.inc | 3 +- repos/pc/src/include/lx_emul/pci_fixups.h | 22 - repos/pc/src/lib/wifi/dummies.c | 33 + repos/pc/src/lib/wifi/generated_dummies.c | 115 +--- repos/pc/src/lib/wifi/lx_emul.c | 30 + repos/pc/src/lib/wifi/spec/x86_32/source.list | 13 - repos/pc/src/lib/wifi/spec/x86_64/source.list | 13 - repos/pc/src/test/driver_time/dummies.c | 9 + .../src/test/driver_time/generated_dummies.c | 191 +++--- repos/pc/src/test/driver_time/source.list | 1 + 53 files changed, 1308 insertions(+), 1835 deletions(-) create mode 100644 repos/dde_linux/src/include/lx_emul/pci.h delete mode 100644 repos/dde_linux/src/include/lx_emul/pci_config_space.h delete mode 100644 repos/dde_linux/src/include/spec/x86/lx_kit/platform_session/connection.h delete mode 100644 repos/dde_linux/src/include/spec/x86/lx_kit/platform_session/device.h create mode 100644 repos/dde_linux/src/lib/lx_emul/pci.cc create mode 100644 repos/dde_linux/src/lib/lx_emul/pci_bus.c delete mode 100644 repos/dde_linux/src/lib/lx_emul/pci_config_space.cc delete mode 100644 repos/dde_linux/src/lib/lx_emul/pci_init.cc create mode 100644 repos/dde_linux/src/lib/lx_emul/shadow/drivers/pci/host-bridge.c create mode 100644 repos/dde_linux/src/lib/lx_emul/shadow/drivers/pci/pci-sysfs.c create mode 100644 repos/dde_linux/src/lib/lx_emul/shadow/drivers/pci/pci.c create mode 100644 repos/dde_linux/src/lib/lx_emul/shadow/drivers/pci/search.c create mode 100644 repos/dde_linux/src/lib/lx_emul/shadow/drivers/pci/setup-irq.c create mode 100644 repos/dde_linux/src/lib/lx_emul/shadow/drivers/pci/setup-res.c delete mode 100644 repos/dde_linux/src/lib/lx_emul/spec/x86/pci.c delete mode 100644 repos/dde_linux/src/lib/lx_kit/spec/x86/platform.cc delete mode 100644 repos/pc/src/drivers/framebuffer/intel/pc/misc.cc create mode 100644 repos/pc/src/drivers/framebuffer/intel/pc/pci.c delete mode 100644 repos/pc/src/include/lx_emul/pci_fixups.h diff --git a/repos/dde_linux/lib/import/import-lx_emul_common.inc b/repos/dde_linux/lib/import/import-lx_emul_common.inc index 6845a15452..600b37b075 100644 --- a/repos/dde_linux/lib/import/import-lx_emul_common.inc +++ b/repos/dde_linux/lib/import/import-lx_emul_common.inc @@ -58,9 +58,6 @@ SPEC_ARCH := x86_32 SRC_C += lx_emul/shadow/arch/x86/kernel/irq.c SRC_C += lx_emul/shadow/arch/x86/kernel/setup_percpu.c - -# temporarily add the following include path for x86 platform_session wrapper -INC_DIR += $(DDE_LINUX_DIR)/src/include/spec/x86/lx_kit endif ifeq ($(filter-out $(SPECS),x86_64),) @@ -70,9 +67,6 @@ SPEC_ARCH := x86_64 SRC_C += lx_emul/shadow/arch/x86/kernel/irq.c SRC_C += lx_emul/shadow/arch/x86/kernel/setup_percpu.c - -# temporarily add the following include path for x86 platform_session wrapper -INC_DIR += $(DDE_LINUX_DIR)/src/include/spec/x86/lx_kit endif ifeq ($(filter-out $(SPECS),arm),) diff --git a/repos/dde_linux/src/drivers/usb_host/spec/x86/target.inc b/repos/dde_linux/src/drivers/usb_host/spec/x86/target.inc index 5b43fc0d6c..71cd68ac4c 100644 --- a/repos/dde_linux/src/drivers/usb_host/spec/x86/target.inc +++ b/repos/dde_linux/src/drivers/usb_host/spec/x86/target.inc @@ -14,7 +14,6 @@ SRC_C += usb/host/uhci-hcd.c SRC_C += usb/host/xhci-pci.c SRC_CC += lx_kit/mapped_io_mem_range.cc -SRC_CC += lx_kit/pci.cc SRC_CC += spec/x86/platform.cc diff --git a/repos/dde_linux/src/include/lx_emul/pci.h b/repos/dde_linux/src/include/lx_emul/pci.h new file mode 100644 index 0000000000..64daed7280 --- /dev/null +++ b/repos/dde_linux/src/include/lx_emul/pci.h @@ -0,0 +1,56 @@ +/* + * \brief Lx_emul support for accessing PCI devices + * \author Stefan Kalkowski + * \date 2022-05-23 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#ifndef _LX_EMUL__PCI_H_ +#define _LX_EMUL__PCI_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*lx_emul_add_resource_callback_t) + (void * dev, + unsigned number, + unsigned long addr, + unsigned long size, + int io_port); + + +typedef void (*lx_emul_add_device_callback_t) + (void * bus, + unsigned number, + char const * const name, + unsigned short vendor_id, + unsigned short device_id, + unsigned short sub_vendor, + unsigned short sub_device, + unsigned int class_code, + unsigned char revision, + unsigned irq); + + +void lx_emul_pci_for_each_resource(const char * const name, void * dev, + lx_emul_add_resource_callback_t fn); + +void lx_emul_pci_for_each_device(void * bus, lx_emul_add_device_callback_t fn); + +void lx_emul_pci_enable(const char * const name); + +void * lx_emul_pci_root_bus(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _LX_EMUL__PCI_H_ */ + diff --git a/repos/dde_linux/src/include/lx_emul/pci_config_space.h b/repos/dde_linux/src/include/lx_emul/pci_config_space.h deleted file mode 100644 index 4ea46796a1..0000000000 --- a/repos/dde_linux/src/include/lx_emul/pci_config_space.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * \brief Lx_emul support for accessing PCI(e) config space - * \author Josef Soentgen - * \date 2022-01-18 - */ - -/* - * Copyright (C) 2022 Genode Labs GmbH - * - * This file is distributed under the terms of the GNU General Public License - * version 2. - */ - -#ifndef _LX_EMUL__PCI_CONFIG_SPACE_H_ -#define _LX_EMUL__PCI_CONFIG_SPACE_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -int lx_emul_pci_read_config(unsigned bus, unsigned devfn, unsigned reg, unsigned len, unsigned *val); -int lx_emul_pci_write_config(unsigned bus, unsigned devfn, unsigned reg, unsigned len, unsigned val); - -#ifdef __cplusplus -} -#endif - -#endif /* _LX_EMUL__PCI_CONFIG_SPACE_H_ */ diff --git a/repos/dde_linux/src/include/lx_kit/device.h b/repos/dde_linux/src/include/lx_kit/device.h index ddf1a80f4e..aa6f1fa713 100644 --- a/repos/dde_linux/src/include/lx_kit/device.h +++ b/repos/dde_linux/src/include/lx_kit/device.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -35,10 +36,7 @@ struct clk { class Lx_kit::Device : List::Element { - private: - - friend class Device_list; - friend class List; + public: using Name = String<64>; using Type = Platform::Device::Type; @@ -47,16 +45,17 @@ class Lx_kit::Device : List::Element { using Index = Platform::Device::Mmio::Index; - Index idx; - addr_t addr; - size_t size; + Index idx; + addr_t addr; + size_t size; + unsigned pci_bar; Constructible io_mem {}; bool match(addr_t addr, size_t size); - Io_mem(unsigned idx, addr_t addr, size_t size) - : idx{idx}, addr(addr), size(size) {} + Io_mem(unsigned idx, addr_t addr, size_t size, unsigned pci_bar) + : idx{idx}, addr(addr), size(size), pci_bar(pci_bar) {} }; struct Irq : List::Element @@ -81,13 +80,15 @@ class Lx_kit::Device : List::Element Index idx; uint16_t addr; uint16_t size; + unsigned pci_bar; Constructible io_port {}; bool match(uint16_t addr); - Io_port(unsigned idx, uint16_t addr, uint16_t size) - : idx{idx}, addr(addr), size(size) {} + Io_port(unsigned idx, uint16_t addr, uint16_t size, + unsigned pci_bar) + : idx{idx}, addr(addr), size(size), pci_bar(pci_bar) {} }; struct Clock : List::Element @@ -100,6 +101,21 @@ class Lx_kit::Device : List::Element : idx(idx), name(name), lx_clock{0} {} }; + struct Pci_config + { + Pci::vendor_t vendor_id; + Pci::device_t device_id; + Pci::class_t class_code; + Pci::rev_t rev; + Pci::vendor_t sub_v_id; + Pci::device_t sub_d_id; + }; + + private: + + friend class Device_list; + friend class List; + Device(Entrypoint & ep, Platform::Connection & plat, Xml_node & xml, @@ -108,23 +124,12 @@ class Lx_kit::Device : List::Element Platform::Connection & _platform; Name const _name; Type const _type; - List _io_mems {}; - List _io_ports {}; - List _irqs {}; - List _clocks {}; - Constructible _pdev {}; - - template - void _for_each_io_mem(FN const & fn) { - for (Io_mem * i = _io_mems.first(); i; i = i->next()) fn(*i); } - - template - void _for_each_io_port(FN const & fn) { - for (Io_port * i = _io_ports.first(); i; i = i->next()) fn(*i); } - - template - void _for_each_irq(FN const & fn) { - for (Irq * i = _irqs.first(); i; i = i->next()) fn(*i); } + List _io_mems {}; + List _io_ports {}; + List _irqs {}; + List _clocks {}; + Constructible _pci_config {}; + Constructible _pdev {}; template void _for_each_clock(FN const & fn) { @@ -133,7 +138,23 @@ class Lx_kit::Device : List::Element public: const char * compatible(); - const char * name(); + Name name(); + + template + void for_each_io_mem(FN const & fn) { + for (Io_mem * i = _io_mems.first(); i; i = i->next()) fn(*i); } + + template + void for_each_io_port(FN const & fn) { + for (Io_port * i = _io_ports.first(); i; i = i->next()) fn(*i); } + + template + void for_each_irq(FN const & fn) { + for (Irq * i = _irqs.first(); i; i = i->next()) fn(*i); } + + template + void for_pci_config(FN const & fn) { + if (_pci_config.constructed()) fn(*_pci_config); } void enable(); clk * clock(const char * name); @@ -163,12 +184,21 @@ class Lx_kit::Device_list : List Platform::Connection & _platform; + void _handle_signal() {} + public: template void for_each(FN const & fn) { for (Device * d = first(); d; d = d->next()) fn(*d); } + template + void with_xml(FN const & fn) + { + _platform.update(); + _platform.with_xml([&] (Xml_node & xml) { fn(xml); }); + } + Device_list(Entrypoint & ep, Heap & heap, Platform::Connection & platform); diff --git a/repos/dde_linux/src/include/spec/x86/lx_kit/platform_session/connection.h b/repos/dde_linux/src/include/spec/x86/lx_kit/platform_session/connection.h deleted file mode 100644 index 8ff8aba1a4..0000000000 --- a/repos/dde_linux/src/include/spec/x86/lx_kit/platform_session/connection.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * \brief Dummy - platform session device interface - * \author Stefan Kalkowski - * \date 2022-01-07 - */ - -/* - * Copyright (C) 2021 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -#ifndef _PLATFORM_SESSION__CONNECTION_H_ -#define _PLATFORM_SESSION__CONNECTION_H_ - -#include -#include -#include -#include -#include - -namespace Platform { - struct Connection; - class Dma_buffer; - - using namespace Genode; -} - -#define Platform Legacy_platform -#include -#undef Platform - - -struct Platform::Connection -{ - Env &_env; - Region_map &_rm { _env.rm() }; - char _devices_node_buffer[4096u] { }; - Constructible _devices_node { }; - - Constructible _legacy_platform { }; - struct Device - { - using Name = String<16>; - - Name name { }; - Legacy_platform::Device_capability cap { }; - - Device(Name const &name, Legacy_platform::Device_capability cap) - : name { name }, cap { cap } { } - }; - - enum : unsigned char { MAX_DEVICES = 4 }; - Constructible _devices_list[MAX_DEVICES] { }; - - Legacy_platform::Device_capability device_cap(char const *name); - - Connection(Env &); - - /******************************** - ** Platform session interface ** - ********************************/ - - void update(); - - template void with_xml(FN const & fn) - { - if (_devices_node.constructed()) - fn(*_devices_node); - } - - Ram_dataspace_capability alloc_dma_buffer(size_t size, Cache cache); - - void free_dma_buffer(Ram_dataspace_capability); - - addr_t dma_addr(Ram_dataspace_capability); - - template - auto retry_with_upgrade(Ram_quota ram, Cap_quota caps, FUNC func) -> decltype(func()) - { - return _legacy_platform->retry_with_upgrade(ram, caps, func); - } -}; - - -#endif /* _PLATFORM_SESSION__CONNECTION_H_ */ diff --git a/repos/dde_linux/src/include/spec/x86/lx_kit/platform_session/device.h b/repos/dde_linux/src/include/spec/x86/lx_kit/platform_session/device.h deleted file mode 100644 index babf70c672..0000000000 --- a/repos/dde_linux/src/include/spec/x86/lx_kit/platform_session/device.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * \brief Dummy - platform session device interface - * \author Stefan Kalkowski - * \date 2022-01-07 - */ - -/* - * Copyright (C) 2021 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -#ifndef _PLATFORM_SESSION__DEVICE_H_ -#define _PLATFORM_SESSION__DEVICE_H_ - -/* Genode includes */ -#include -#include -#include -#include -#include -#include -#include -#include - - -namespace Platform { - struct Connection; - class Device; - - using namespace Genode; -} - - -class Platform::Device : Interface, Noncopyable -{ - public: - - struct Range { addr_t start; size_t size; }; - - struct Mmio; - struct Io_port_range; - struct Irq; - struct Config_space; - - using Name = String<64>; - - private: - - Connection &_platform; - Legacy_platform::Device_capability _device_cap { }; - Name _name { }; - unsigned _class_code { }; - - public: - - int _bar_checked_for_size[6] { }; - - struct Index { unsigned value; }; - - explicit Device(Connection &platform) - : _platform { platform } { } - - struct Type { String<64> name; }; - - Device(Connection &platform, Type type); - - Device(Connection &platform, Name name); - - ~Device() { } - - Name const &name() const - { - return _name; - } -}; - - -class Platform::Device::Mmio : Range -{ - public: - - struct Index { unsigned value; }; - - private: - - Constructible _attached_ds { }; - - void *_local_addr(); - - Device &_device; - Index _index; - - public: - - Mmio(Device &device, Index index) - : _device { device }, _index { index } { } - - explicit Mmio(Device &device) - : _device { device }, _index { ~0u } { } - - size_t size() const; - - template - T *local_addr() { return reinterpret_cast(_local_addr()); } -}; - - -class Platform::Device::Io_port_range : Noncopyable -{ - public: - - struct Index { unsigned value; }; - - private: - - Device &_device; - Index _index; - - Constructible _io_port { }; - - public: - - Io_port_range(Device &device, Index index); - - explicit Io_port_range(Device &device) - : _device { device }, _index { ~0u } { } - - uint8_t inb(uint16_t addr); - uint16_t inw(uint16_t addr); - uint32_t inl(uint16_t addr); - - void outb(uint16_t addr, uint8_t val); - void outw(uint16_t addr, uint16_t val); - void outl(uint16_t addr, uint32_t val); -}; - - -class Platform::Device::Irq : Noncopyable -{ - public: - - struct Index { unsigned value; }; - - private: - - Device &_device; - Index _index; - - Constructible _irq { }; - - public: - - Irq(Device &device, Index index); - - explicit Irq(Device &device) - : _device { device }, _index { ~0u } { } - - void ack(); - void sigh(Signal_context_capability); - void sigh_omit_initial_signal(Signal_context_capability); -}; - - -class Platform::Device::Config_space : Noncopyable -{ - public: - - Device &_device; - - enum class Access_size : unsigned { ACCESS_8BIT, ACCESS_16BIT, ACCESS_32BIT }; - - Config_space(Device &device) : _device { device } { } - - unsigned read(unsigned char address, Access_size size); - void write(unsigned char address, unsigned value, Access_size size); -}; - - -#endif /* _PLATFORM_SESSION__DEVICE_H_ */ diff --git a/repos/dde_linux/src/lib/lx_emul/pci.cc b/repos/dde_linux/src/lib/lx_emul/pci.cc new file mode 100644 index 0000000000..713492293a --- /dev/null +++ b/repos/dde_linux/src/lib/lx_emul/pci.cc @@ -0,0 +1,104 @@ +/* + * \brief Lx_emul backend for PCI devices + * \author Stefan Kalkowski + * \date 2022-05-23 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#include +#include +#include +#include +#include + +extern "C" void lx_emul_pci_enable(const char * const name) +{ + using namespace Lx_kit; + + env().devices.for_each([&] (Device & d) { + if (d.name() == name) d.enable(); }); +}; + + +extern "C" void +lx_emul_pci_for_each_resource(const char * const name, void * dev, + lx_emul_add_resource_callback_t fn) +{ + using namespace Lx_kit; + using namespace Genode; + using namespace Pci; + + env().devices.for_each([&] (Device & d) { + if (d.name() != name) + return; + + d.for_each_io_mem([&] (Device::Io_mem & io_mem) { + fn(dev, io_mem.pci_bar, io_mem.addr, io_mem.size, 0); + }); + + d.for_each_io_port([&] (Device::Io_port & io_port) { + fn(dev, io_port.pci_bar, io_port.addr, io_port.size, 1); + }); + }); +} + + +extern "C" void +lx_emul_pci_for_each_device(void * bus, lx_emul_add_device_callback_t fn) +{ + using namespace Lx_kit; + using namespace Genode; + using namespace Pci; + + unsigned num = 0; + env().devices.for_each([&] (Device & d) { + unsigned irq = 0; + d.for_each_irq([&] (Device::Irq & i) { + if (!irq) irq = i.number; }); + + d.for_pci_config([&] (Device::Pci_config & cfg) { + fn(bus, num++, d.name().string(), cfg.vendor_id, cfg.device_id, + cfg.sub_v_id, cfg.sub_d_id, cfg.class_code, cfg.rev, irq); + }); + }); +} + + +static const char * lx_emul_pci_final_fixups[] = { + "__pci_fixup_final_quirk_usb_early_handoff", + "END_OF_PCI_FIXUPS" +}; + + +extern "C" __attribute__((weak)) int inhibit_pci_fixup(char const *) +{ + return 0; +} + + +extern "C" void lx_emul_register_pci_fixup(void (*fn)(struct pci_dev*), const char * name) +{ + if (inhibit_pci_fixup(name)) + return; + + for (unsigned i = 0; i < (sizeof(lx_emul_pci_final_fixups) / sizeof(char*)); + i++) { + if (Genode::strcmp(name, lx_emul_pci_final_fixups[i]) == 0) { + Lx_kit::env().pci_fixup_calls.add(fn); + return; + } + } + Genode::error(__func__, " ignore unkown PCI fixup '", name, "'"); +} + + +extern "C" void lx_emul_execute_pci_fixup(struct pci_dev *pci_dev) +{ + Lx_kit::env().pci_fixup_calls.execute(pci_dev); +} diff --git a/repos/dde_linux/src/lib/lx_emul/pci_bus.c b/repos/dde_linux/src/lib/lx_emul/pci_bus.c new file mode 100644 index 0000000000..ec0fe9691d --- /dev/null +++ b/repos/dde_linux/src/lib/lx_emul/pci_bus.c @@ -0,0 +1,199 @@ +/* + * \brief PCI backend + * \author Josef Soentgen + * \date 2022-05-10 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#include +#include +#include + +#include +#include +#include + + +extern void lx_backtrace(void); + + +int arch_probe_nr_irqs(void) +{ + /* needed for 'irq_get_irq_data()' in 'pci_assign_irq()' below */ + return 256; +} + + +static const struct attribute_group *pci_dev_attr_groups[] = { + NULL, +}; + + +const struct device_type pci_dev_type = { + .groups = pci_dev_attr_groups, +}; + + +extern const struct device_type pci_dev_type; + + +static struct pci_bus *_pci_bus; + + +void * lx_emul_pci_root_bus() +{ + return _pci_bus; +} + + +static struct device * host_bridge_device = NULL; +extern struct device * pci_get_host_bridge_device(struct pci_dev * dev); +struct device * pci_get_host_bridge_device(struct pci_dev * dev) +{ + return host_bridge_device; +} + + +static struct pci_dev *_pci_alloc_dev(struct pci_bus *bus) +{ + struct pci_dev *dev; + + dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL); + if (!dev) + return NULL; + + INIT_LIST_HEAD(&dev->bus_list); + dev->dev.type = &pci_dev_type; + dev->bus = bus; + + return dev; +} + + +static void pci_add_resource_to_device_callback(void * data, + unsigned number, + unsigned long addr, + unsigned long size, + int io_port) +{ + struct pci_dev * dev = (struct pci_dev*) data; + dev->resource[number].start = addr; + dev->resource[number].end = dev->resource[number].start + size - 1; + if (io_port) + dev->resource[number].flags |= IORESOURCE_IO; +} + + +static void pci_add_single_device_callback(void * data, + unsigned number, + char const * const name, + u16 vendor_id, + u16 device_id, + u16 sub_vendor, + u16 sub_device, + u32 class_code, + u8 revision, + unsigned irq) +{ + struct pci_bus * bus = (struct pci_bus*) data; + struct pci_dev * dev = _pci_alloc_dev(bus); + + if (!dev) { + printk("Error: out of memory, cannot allocate pci device %s\n", name); + return; + } + + dev->devfn = number * 8; + dev->vendor = vendor_id; + dev->device = device_id; + dev->subsystem_vendor = sub_vendor; + dev->subsystem_device = sub_device; + dev->irq = irq; + dev->dma_mask = 0xffffffff; + dev->dev.bus = &pci_bus_type; + dev->revision = revision; + dev->class = class_code; + dev->current_state = PCI_UNKNOWN; + + lx_emul_pci_for_each_resource(name, dev, + pci_add_resource_to_device_callback); + + list_add_tail(&dev->bus_list, &bus->devices); + + device_initialize(&dev->dev); + + dev_set_name(&dev->dev, name); + dev->dev.dma_mask = &dev->dma_mask; + + if (number == 0) { /* host bridge */ + host_bridge_device = &dev->dev; + bus->bridge = &dev->dev; + } + + dev->match_driver = false; + if (device_add(&dev->dev)) { + list_del(&dev->bus_list); + kfree(dev); + printk("Error: could not add pci device %s\n", name); + return; + } + + lx_emul_execute_pci_fixup(dev); + + dev->match_driver = true; + if (device_attach(&dev->dev)) { + list_del(&dev->bus_list); + kfree(dev); + printk("Error: could not attach pci device %s\n", name); + return; + } +} + + +static int __init pci_subsys_init(void) +{ + struct pci_bus *b; + struct pci_sysdata *sd; + + /* pci_alloc_bus(NULL) */ + b = kzalloc(sizeof (struct pci_bus), GFP_KERNEL); + if (!b) + return -ENOMEM; + + sd = kzalloc(sizeof (struct pci_sysdata), GFP_KERNEL); + if (!sd) { + kfree(b); + return -ENOMEM; + } + + /* needed by intel_fb */ + sd->domain = 0; + + b->sysdata = sd; + + INIT_LIST_HEAD(&b->node); + INIT_LIST_HEAD(&b->children); + INIT_LIST_HEAD(&b->devices); + INIT_LIST_HEAD(&b->slots); + INIT_LIST_HEAD(&b->resources); + b->max_bus_speed = PCI_SPEED_UNKNOWN; + b->cur_bus_speed = PCI_SPEED_UNKNOWN; + + _pci_bus = b; + + /* add host bridge device */ + pci_add_single_device_callback(b, 0, "00:00.0", 0x8086, 0x44, 0x17aa, 0x2193, 0x60000, 2, 0); + + /* attach PCI devices */ + lx_emul_pci_for_each_device(b, pci_add_single_device_callback); + return 0; +} + + +subsys_initcall(pci_subsys_init); diff --git a/repos/dde_linux/src/lib/lx_emul/pci_config_space.cc b/repos/dde_linux/src/lib/lx_emul/pci_config_space.cc deleted file mode 100644 index 3fb22b4c72..0000000000 --- a/repos/dde_linux/src/lib/lx_emul/pci_config_space.cc +++ /dev/null @@ -1,82 +0,0 @@ -/* - * \brief Lx_emul backend for accessing PCI(e) config space - * \author Josef Soentgen - * \date 2022-01-18 - */ - -/* - * Copyright (C) 2022 Genode Labs GmbH - * - * This file is distributed under the terms of the GNU General Public License - * version 2. - */ - -#include -#include - - -using Device_name = Genode::String<16>; - -template -static Device_name to_string(T const &arg, TAIL &&... args) -{ - return Device_name(arg, args...); -} - - -static Device_name assemble(unsigned bus, unsigned devfn) -{ - using namespace Genode; - return to_string("pci-", - Hex(bus, Hex::OMIT_PREFIX), ":", - Hex((devfn >> 3) & 0x1fu, Hex::OMIT_PREFIX), ".", - Hex(devfn & 0x7u, Hex::OMIT_PREFIX)); -} - - -int lx_emul_pci_read_config(unsigned bus, unsigned devfn, - unsigned reg, unsigned len, unsigned *val) -{ - using namespace Lx_kit; - using namespace Genode; - - Device_name name = assemble(bus, devfn); - - bool result = false; - bool matched = false; - - env().devices.for_each([&] (Device & d) { - matched = name == d.name(); - if (matched && val) - result = d.read_config(reg, len, val); - }); - - if (!result && matched) - error("could not read config space register ", Hex(reg)); - - return result ? 0 : -1; -} - - -int lx_emul_pci_write_config(unsigned bus, unsigned devfn, - unsigned reg, unsigned len, unsigned val) -{ - using namespace Lx_kit; - using namespace Genode; - - Device_name name = assemble(bus, devfn); - - bool result = false; - bool matched = false; - env().devices.for_each ([&] (Device & d) { - matched = name == d.name(); - if (matched) - result = d.write_config(reg, len, val); - }); - - if (!result && matched) - error("could not write config space register ", Hex(reg), - " with ", Hex(val)); - - return result ? 0 : -1; -} diff --git a/repos/dde_linux/src/lib/lx_emul/pci_init.cc b/repos/dde_linux/src/lib/lx_emul/pci_init.cc deleted file mode 100644 index b20b2b1e59..0000000000 --- a/repos/dde_linux/src/lib/lx_emul/pci_init.cc +++ /dev/null @@ -1,46 +0,0 @@ -/* - * \brief Lx_emul backend for PCI fixup calls - * \author Josef Soentgen - * \date 2022-02-04 - */ - -/* - * Copyright (C) 2022 Genode Labs GmbH - * - * This file is distributed under the terms of the GNU General Public License - * version 2. - */ - -#include -#include -#include - -#include - - -extern "C" __attribute__((weak)) int inhibit_pci_fixup(char const *) -{ - return 0; -} - - -extern "C" void lx_emul_register_pci_fixup(void (*fn)(struct pci_dev*), const char * name) -{ - if (inhibit_pci_fixup(name)) - return; - - for (unsigned i = 0; i < (sizeof(lx_emul_pci_final_fixups) / sizeof(char*)); - i++) { - if (Genode::strcmp(name, lx_emul_pci_final_fixups[i]) == 0) { - Lx_kit::env().pci_fixup_calls.add(fn); - return; - } - } - Genode::error(__func__, " ignore unkown PCI fixup '", name, "'"); -} - - -extern "C" void lx_emul_execute_pci_fixup(struct pci_dev *pci_dev) -{ - Lx_kit::env().pci_fixup_calls.execute(pci_dev); -} diff --git a/repos/dde_linux/src/lib/lx_emul/shadow/drivers/pci/host-bridge.c b/repos/dde_linux/src/lib/lx_emul/shadow/drivers/pci/host-bridge.c new file mode 100644 index 0000000000..7d86619469 --- /dev/null +++ b/repos/dde_linux/src/lib/lx_emul/shadow/drivers/pci/host-bridge.c @@ -0,0 +1,11 @@ +#include + +void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region, + struct resource *res) +{ + region->start = res->start; + region->end = res->end; +} + + +void pci_put_host_bridge_device(struct device * dev) { } diff --git a/repos/dde_linux/src/lib/lx_emul/shadow/drivers/pci/pci-sysfs.c b/repos/dde_linux/src/lib/lx_emul/shadow/drivers/pci/pci-sysfs.c new file mode 100644 index 0000000000..174228d7de --- /dev/null +++ b/repos/dde_linux/src/lib/lx_emul/shadow/drivers/pci/pci-sysfs.c @@ -0,0 +1,34 @@ +#include + +static struct attribute *pci_bus_attrs[] = { + NULL, +}; + + +static const struct attribute_group pci_bus_group = { + .attrs = pci_bus_attrs, +}; + + +const struct attribute_group *pci_bus_groups[] = { + &pci_bus_group, + NULL, +}; + + +static struct attribute *pci_dev_attrs[] = { + NULL, +}; + + +static const struct attribute_group pci_dev_group = { + .attrs = pci_dev_attrs, +}; + + +const struct attribute_group *pci_dev_groups[] = { + &pci_dev_group, + NULL, +}; + + diff --git a/repos/dde_linux/src/lib/lx_emul/shadow/drivers/pci/pci.c b/repos/dde_linux/src/lib/lx_emul/shadow/drivers/pci/pci.c new file mode 100644 index 0000000000..f9fc4b7aae --- /dev/null +++ b/repos/dde_linux/src/lib/lx_emul/shadow/drivers/pci/pci.c @@ -0,0 +1,36 @@ +#include +#include + +int pci_enable_device(struct pci_dev * dev) +{ + lx_emul_pci_enable(dev_name(&dev->dev)); + return 0; +} + + +int pcim_enable_device(struct pci_dev *pdev) +{ + /* for now ignore devres */ + return pci_enable_device(pdev); +} + + +void pci_set_master(struct pci_dev * dev) { } + + +int pci_set_mwi(struct pci_dev * dev) +{ + return 1; +} + + +bool pci_dev_run_wake(struct pci_dev * dev) +{ + return false; +} + + +u8 pci_find_capability(struct pci_dev * dev,int cap) +{ + return 0; +} diff --git a/repos/dde_linux/src/lib/lx_emul/shadow/drivers/pci/search.c b/repos/dde_linux/src/lib/lx_emul/shadow/drivers/pci/search.c new file mode 100644 index 0000000000..ea12ef7fab --- /dev/null +++ b/repos/dde_linux/src/lib/lx_emul/shadow/drivers/pci/search.c @@ -0,0 +1,44 @@ +#include +#include + +struct pci_dev * pci_get_class(unsigned int class, struct pci_dev *from) +{ + struct pci_dev *dev; + struct pci_bus *bus = (struct pci_bus *) lx_emul_pci_root_bus(); + + /* + * Break endless loop (see 'intel_dsm_detect()') by only querying + * the bus on the first executuin. + */ + if (from) + return NULL; + + list_for_each_entry(dev, &bus->devices, bus_list) { + if (dev->class == class) { + return dev; + } + } + + return NULL; +} + + +struct pci_dev *pci_get_domain_bus_and_slot(int domain, unsigned int bus, + unsigned int devfn) +{ + struct pci_dev *dev; + struct pci_bus *pbus = (struct pci_bus *) lx_emul_pci_root_bus(); + + list_for_each_entry(dev, &pbus->devices, bus_list) { + if (dev->devfn == devfn && dev->class == 0x60000) + return dev; + } + + return NULL; +} + + +struct pci_dev * pci_get_device(unsigned int vendor,unsigned int device,struct pci_dev * from) +{ + return NULL; +} diff --git a/repos/dde_linux/src/lib/lx_emul/shadow/drivers/pci/setup-irq.c b/repos/dde_linux/src/lib/lx_emul/shadow/drivers/pci/setup-irq.c new file mode 100644 index 0000000000..51f668b44e --- /dev/null +++ b/repos/dde_linux/src/lib/lx_emul/shadow/drivers/pci/setup-irq.c @@ -0,0 +1,24 @@ +#include +#include + +extern struct irq_chip dde_irqchip_data_chip; + + +void pci_assign_irq(struct pci_dev * dev) +{ + struct irq_data *irq_data; + + /* + * Be lazy and treat irq as hwirq as this is used by the + * dde_irqchip_data_chip for (un-)masking. + */ + irq_data = irq_get_irq_data(dev->irq); + + irq_data->hwirq = dev->irq; + + irq_set_chip_and_handler(dev->irq, &dde_irqchip_data_chip, + handle_level_irq); +} + + + diff --git a/repos/dde_linux/src/lib/lx_emul/shadow/drivers/pci/setup-res.c b/repos/dde_linux/src/lib/lx_emul/shadow/drivers/pci/setup-res.c new file mode 100644 index 0000000000..1d54d06eb9 --- /dev/null +++ b/repos/dde_linux/src/lib/lx_emul/shadow/drivers/pci/setup-res.c @@ -0,0 +1,11 @@ +#include + +resource_size_t __weak pcibios_align_resource(void *data, + const struct resource *res, + resource_size_t size, + resource_size_t align) +{ + return res->start; +} + + diff --git a/repos/dde_linux/src/lib/lx_emul/spec/x86/pci.c b/repos/dde_linux/src/lib/lx_emul/spec/x86/pci.c deleted file mode 100644 index 35d208d10d..0000000000 --- a/repos/dde_linux/src/lib/lx_emul/spec/x86/pci.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * \brief Linux kernel PCI - * \author Josef Soentgen - * \date 2022-01-14 - */ - -/* - * Copyright (C) 2022 Genode Labs GmbH - * - * This file is distributed under the terms of the GNU General Public License - * version 2. - */ - -#include -#include - - -#include - -int arch_probe_nr_irqs(void) -{ - return 16; -} - - -#include - -static int x86_init_pci_init(void) -{ - return 1; -} - - -static void x86_init_pci_init_irq(void) { } - - -struct x86_init_ops x86_init = { - .pci = { - .init = x86_init_pci_init, - .init_irq = x86_init_pci_init_irq, - }, -}; - - -#include - -#include -#include -#include - -static int pci_raw_ops_read(unsigned int domain, unsigned int bus, unsigned int devfn, - int reg, int len, u32 *val) -{ - return lx_emul_pci_read_config(bus, devfn, (unsigned)reg, (unsigned)len, val); -} - - -static int pci_raw_ops_write(unsigned int domain, unsigned int bus, unsigned int devfn, - int reg, int len, u32 val) -{ - return lx_emul_pci_write_config(bus, devfn, (unsigned)reg, (unsigned)len, val); -} - - -const struct pci_raw_ops genode_raw_pci_ops = { - .read = pci_raw_ops_read, - .write = pci_raw_ops_write, -}; - -const struct pci_raw_ops *raw_pci_ops = &genode_raw_pci_ops; - - -static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) -{ - return pci_raw_ops_read(0, bus->number, devfn, where, size, value); -} - - -static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value) -{ - return pci_raw_ops_write(0, bus->number, devfn, where, size, value); -} - - -struct pci_ops pci_root_ops = { - .read = pci_read, - .write = pci_write, -}; - - -#include - -static struct resource _dummy_parent; - -void pcibios_scan_root(int busnum) -{ - struct pci_bus *bus; - struct pci_sysdata *sd; - struct pci_dev *dev; - - LIST_HEAD(resources); - - sd = kzalloc(sizeof(*sd), GFP_KERNEL); - if (!sd) { - return; - } - sd->node = NUMA_NO_NODE; - pci_add_resource(&resources, &ioport_resource); - pci_add_resource(&resources, &iomem_resource); - - bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, sd, &resources); - - if (!bus) { - pci_free_resource_list(&resources); - kfree(sd); - return; - } - pci_bus_add_devices(bus); - - /* handle early quirks */ - list_for_each_entry(dev, &bus->devices, bus_list) { - - /* - * As pci_enable_resources() is only going to check if - * the parent of the resource is set register the dummy. - */ - struct resource *r; - int i; - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - - r = &dev->resource[i]; - r->parent = &_dummy_parent; - } - - lx_emul_execute_pci_fixup(dev); - } -} - - -#include -#include - -extern struct irq_chip dde_irqchip_data_chip; - - -void pci_assign_irq(struct pci_dev * dev) -{ - struct irq_data *irq_data; - - /* - * Be lazy and treat irq as hwirq as this is used by the - * dde_irqchip_data_chip for (un-)masking. - */ - irq_data = irq_get_irq_data(dev->irq); - irq_data->hwirq = dev->irq; - - irq_set_chip_and_handler(dev->irq, &dde_irqchip_data_chip, - handle_level_irq); -} - - -#include - -unsigned long pci_mem_start = 0xaeedbabe; - -const struct attribute_group aspm_ctrl_attr_group[] = { 0 }; -const struct attribute_group pci_dev_vpd_attr_group = { }; - -struct pci_fixup __start_pci_fixups_early[] = { 0 }; -struct pci_fixup __end_pci_fixups_early[] = { 0 }; -struct pci_fixup __start_pci_fixups_header[] = { 0 }; -struct pci_fixup __end_pci_fixups_header[] = { 0 }; -struct pci_fixup __start_pci_fixups_final[] = { 0 }; -struct pci_fixup __end_pci_fixups_final[] = { 0 }; -struct pci_fixup __start_pci_fixups_enable[] = { 0 }; -struct pci_fixup __end_pci_fixups_enable[] = { 0 }; -struct pci_fixup __start_pci_fixups_resume[] = { 0 }; -struct pci_fixup __end_pci_fixups_resume[] = { 0 }; -struct pci_fixup __start_pci_fixups_resume_early[] = { 0 }; -struct pci_fixup __end_pci_fixups_resume_early[] = { 0 }; -struct pci_fixup __start_pci_fixups_suspend[] = { 0 }; -struct pci_fixup __end_pci_fixups_suspend[] = { 0 }; -struct pci_fixup __start_pci_fixups_suspend_late[] = { 0 }; -struct pci_fixup __end_pci_fixups_suspend_late[] = { 0 }; - -int pcibios_last_bus = -1; - - -extern int __init pcibios_init(void); -int __init pcibios_init(void) -{ - lx_emul_trace(__func__); - return 0; -} diff --git a/repos/dde_linux/src/lib/lx_kit/device.cc b/repos/dde_linux/src/lib/lx_kit/device.cc index 88e54b1dd4..de52007ed2 100644 --- a/repos/dde_linux/src/lib/lx_kit/device.cc +++ b/repos/dde_linux/src/lib/lx_kit/device.cc @@ -34,7 +34,7 @@ bool Device::Io_mem::match(addr_t addr, size_t size) bool Device::Io_port::match(uint16_t addr) { return (this->addr <= addr) && - ((this->addr + this->size) >= addr); + ((this->addr + this->size) > addr); } @@ -67,9 +67,9 @@ const char * Device::compatible() } -const char * Device::name() +Device::Name Device::name() { - return _name.string(); + return _name; } @@ -102,7 +102,7 @@ clk * Device::clock(unsigned idx) bool Device::io_mem(addr_t phys_addr, size_t size) { bool ret = false; - _for_each_io_mem([&] (Io_mem & io) { + for_each_io_mem([&] (Io_mem & io) { if (io.match(phys_addr, size)) ret = true; }); @@ -113,7 +113,7 @@ bool Device::io_mem(addr_t phys_addr, size_t size) void * Device::io_mem_local_addr(addr_t phys_addr, size_t size) { void * ret = nullptr; - _for_each_io_mem([&] (Io_mem & io) { + for_each_io_mem([&] (Io_mem & io) { if (!io.match(phys_addr, size)) return; @@ -132,7 +132,7 @@ bool Device::irq_unmask(unsigned number) { bool ret = false; - _for_each_irq([&] (Irq & irq) { + for_each_irq([&] (Irq & irq) { if (irq.number != number) return; @@ -156,7 +156,7 @@ void Device::irq_mask(unsigned number) if (!_pdev.constructed()) return; - _for_each_irq([&] (Irq & irq) { + for_each_irq([&] (Irq & irq) { if (irq.number != number) return; irq.session.destruct(); @@ -170,7 +170,7 @@ void Device::irq_ack(unsigned number) if (!_pdev.constructed()) return; - _for_each_irq([&] (Irq & irq) { + for_each_irq([&] (Irq & irq) { if (irq.number != number || !irq.session.constructed()) return; irq.session->ack(); @@ -181,7 +181,7 @@ void Device::irq_ack(unsigned number) bool Device::io_port(uint16_t addr) { bool ret = false; - _for_each_io_port([&] (Io_port & io) { + for_each_io_port([&] (Io_port & io) { if (io.match(addr)) ret = true; }); @@ -192,7 +192,7 @@ bool Device::io_port(uint16_t addr) uint8_t Device::io_port_inb(uint16_t addr) { uint8_t ret = 0; - _for_each_io_port([&] (Device::Io_port & io) { + for_each_io_port([&] (Device::Io_port & io) { if (!io.match(addr)) return; @@ -209,7 +209,7 @@ uint8_t Device::io_port_inb(uint16_t addr) uint16_t Device::io_port_inw(uint16_t addr) { uint16_t ret = 0; - _for_each_io_port([&] (Device::Io_port & io) { + for_each_io_port([&] (Device::Io_port & io) { if (!io.match(addr)) return; @@ -226,7 +226,7 @@ uint16_t Device::io_port_inw(uint16_t addr) uint32_t Device::io_port_inl(uint16_t addr) { uint32_t ret = 0; - _for_each_io_port([&] (Device::Io_port & io) { + for_each_io_port([&] (Device::Io_port & io) { if (!io.match(addr)) return; @@ -242,7 +242,7 @@ uint32_t Device::io_port_inl(uint16_t addr) void Device::io_port_outb(uint16_t addr, uint8_t val) { - _for_each_io_port([&] (Device::Io_port & io) { + for_each_io_port([&] (Device::Io_port & io) { if (!io.match(addr)) return; @@ -256,7 +256,7 @@ void Device::io_port_outb(uint16_t addr, uint8_t val) void Device::io_port_outw(uint16_t addr, uint16_t val) { - _for_each_io_port([&] (Device::Io_port & io) { + for_each_io_port([&] (Device::Io_port & io) { if (!io.match(addr)) return; @@ -270,7 +270,7 @@ void Device::io_port_outw(uint16_t addr, uint16_t val) void Device::io_port_outl(uint16_t addr, uint32_t val) { - _for_each_io_port([&] (Device::Io_port & io) { + for_each_io_port([&] (Device::Io_port & io) { if (!io.match(addr)) return; @@ -317,16 +317,18 @@ Device::Device(Entrypoint & ep, { unsigned i = 0; xml.for_each_sub_node("io_mem", [&] (Xml_node node) { - addr_t addr = node.attribute_value("phys_addr", 0UL); - size_t size = node.attribute_value("size", 0UL); - _io_mems.insert(new (heap) Io_mem(i++, addr, size)); + addr_t addr = node.attribute_value("phys_addr", 0UL); + size_t size = node.attribute_value("size", 0UL); + unsigned bar = node.attribute_value("pci_bar", 0U); + _io_mems.insert(new (heap) Io_mem(i++, addr, size, bar)); }); i = 0; - xml.for_each_sub_node("io_port", [&] (Xml_node node) { + xml.for_each_sub_node("io_port_range", [&] (Xml_node node) { uint16_t addr = node.attribute_value("phys_addr", 0U); uint16_t size = node.attribute_value("size", 0U); - _io_ports.insert(new (heap) Io_port(i++, addr, size)); + unsigned bar = node.attribute_value("pci_bar", 0U); + _io_ports.insert(new (heap) Io_port(i++, addr, size, bar)); }); i = 0; @@ -339,6 +341,17 @@ Device::Device(Entrypoint & ep, Device::Name name = node.attribute_value("name", Device::Name()); _clocks.insert(new (heap) Device::Clock(i++, name)); }); + + xml.for_each_sub_node("pci-config", [&] (Xml_node node) { + using namespace Pci; + _pci_config.construct(Pci_config{ + node.attribute_value("vendor_id", 0xffff), + node.attribute_value("device_id", 0xffff), + node.attribute_value("class", 0xff), + node.attribute_value("revision", 0xff), + node.attribute_value("sub_vendor_id", 0xffff), + node.attribute_value("sub_device_id", 0xffff)}); + }); } @@ -352,9 +365,26 @@ Device_list::Device_list(Entrypoint & ep, : _platform(platform) { - _platform.with_xml([&] (Xml_node & xml) { - xml.for_each_sub_node("device", [&] (Xml_node node) { - insert(new (heap) Device(ep, _platform, node, heap)); + bool initialized = false; + Constructible> handler {}; + + while (!initialized) { + _platform.update(); + _platform.with_xml([&] (Xml_node & xml) { + if (!xml.num_sub_nodes()) { + if (!handler.constructed()) { + handler.construct(ep, *this, &Device_list::_handle_signal); + _platform.sigh(*handler); + } + ep.wait_and_dispatch_one_io_signal(); + } else { + _platform.sigh(Signal_context_capability()); + handler.destruct(); + xml.for_each_sub_node("device", [&] (Xml_node node) { + insert(new (heap) Device(ep, _platform, node, heap)); + }); + initialized = true; + } }); - }); + } } diff --git a/repos/dde_linux/src/lib/lx_kit/spec/x86/platform.cc b/repos/dde_linux/src/lib/lx_kit/spec/x86/platform.cc deleted file mode 100644 index c1ea9d3fbb..0000000000 --- a/repos/dde_linux/src/lib/lx_kit/spec/x86/platform.cc +++ /dev/null @@ -1,581 +0,0 @@ -/* - * \brief Legacy platform session wrapper - * \author Josef Soentgen - * \date 2022-01-14 - */ - -/* - * Copyright (C) 2022 Genode Labs GmbH - * - * This file is distributed under the terms of the GNU General Public License - * version 2. - */ - -/* Genode includes */ -#include -#include - -/* DDE includes */ -#include -#include -#include - - -using namespace Genode; - - -using Str = String<16>; - -template -static Str to_string(T const &arg, TAIL &&... args) -{ - return Str(arg, args...); -} - - -template -static void scan_resources(Legacy_platform::Device &device, - FN const &fn) -{ - using R = Legacy_platform::Device::Resource; - for (unsigned resource_id = 0; resource_id < 6; resource_id++) { - - R const resource = device.resource(resource_id); - if (resource.type() != R::INVALID) - fn(resource_id, resource); - } -} - - -static Str create_device_node(Xml_generator &xml, - Legacy_platform::Device &device) -{ - using namespace Genode; - - /* start arbitrarily and count up */ - static unsigned char irq = 8; - - /* start arbitrarily at the dev 1 for the first device */ - static unsigned char bdf[3] = { 0, 1, 0 }; - - /* start arbitrarily at 1 GiB */ - static unsigned long mmio_phys_addr = 0x40000000; - - unsigned char pbdf[3]; - device.bus_address(&pbdf[0], &pbdf[1], &pbdf[2]); - - /* - * The host-bridge is only required by the Intel framebuffer - * driver and has to be located at 00:00.0. For every other - * type of device we simply count upwards. - */ - unsigned char vbdf[3] = { 0, 0, 0 }; - unsigned const class_code = device.class_code() >> 8; - if (class_code != 0x600 /* host-bridge */) { - vbdf[0] = bdf[0]; vbdf[1] = bdf[1]; vbdf[2] = bdf[2]; - bdf[1]++; - } - - log("override physical BDF ", - Hex(pbdf[0], Hex::OMIT_PREFIX), ":", - Hex(pbdf[1], Hex::OMIT_PREFIX), ".", - Hex(pbdf[2], Hex::OMIT_PREFIX), " -> ", - Hex(vbdf[0], Hex::OMIT_PREFIX), ":", - Hex(vbdf[1], Hex::OMIT_PREFIX), ".", - Hex(vbdf[2], Hex::OMIT_PREFIX)); - - Str name = to_string("pci-", - Hex(vbdf[0], Hex::OMIT_PREFIX), ":", - Hex(vbdf[1], Hex::OMIT_PREFIX), ".", - Hex(vbdf[2], Hex::OMIT_PREFIX)); - - xml.node("device", [&] () { - xml.attribute("name", name); - xml.attribute("type", "pci"); - - xml.node("irq", [&] () { - xml.attribute("number", irq++); - }); - - using R = Legacy_platform::Device::Resource; - - scan_resources(device, [&] (unsigned id, R const &r) { - - bool const memory = r.type() == R::MEMORY; - - 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); - }); - - 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); - }); - } - }); - }); - - return name; -} - - -Platform::Connection::Connection(Env &env) -: - _env { env } -{ - try { - _legacy_platform.construct(env); - } catch (...) { - error("could not construct legacy platform connection"); - throw; - } - - /* empirically determined */ - _legacy_platform->upgrade_ram(32768); - _legacy_platform->upgrade_caps(8); - - Xml_generator xml { _devices_node_buffer, - sizeof (_devices_node_buffer), - "devices", [&] () { - _legacy_platform->with_upgrade([&] () { - - /* scan the virtual bus but limit to MAX_DEVICES */ - Legacy_platform::Device_capability cap { }; - for (auto &dev : _devices_list) { - - cap = _legacy_platform->next_device(cap, 0x0u, 0x0u); - if (!cap.valid()) break; - - Legacy_platform::Device_client device { cap }; - Str name = create_device_node(xml, device); - dev.construct(name, cap); - } - }); - } }; - - _devices_node.construct(_devices_node_buffer, - sizeof (_devices_node_buffer)); -} - - -Legacy_platform::Device_capability -Platform::Connection::device_cap(char const *name) -{ - for (auto const &dev : _devices_list) { - if (!dev.constructed()) - continue; - - if (dev->name == name) - return dev->cap; - } - - return Legacy_platform::Device_capability(); -} - - -void Platform::Connection::update() { } - - -Ram_dataspace_capability -Platform::Connection::alloc_dma_buffer(size_t size, Cache) -{ - return _legacy_platform->with_upgrade([&] () { - return _legacy_platform->alloc_dma_buffer(size, Cache::UNCACHED); - }); -} - - -void Platform::Connection::free_dma_buffer(Ram_dataspace_capability ds_cap) -{ - _legacy_platform->free_dma_buffer(ds_cap); -} - - -addr_t Platform::Connection::dma_addr(Ram_dataspace_capability ds_cap) -{ - return _legacy_platform->dma_addr(ds_cap); -} - - -static Legacy_platform::Device::Access_size convert(Platform::Device::Config_space::Access_size size) -{ - using PAS = Platform::Device::Config_space::Access_size; - using LAS = Legacy_platform::Device::Access_size; - switch (size) { - case PAS::ACCESS_8BIT: - return LAS::ACCESS_8BIT; - case PAS::ACCESS_16BIT: - return LAS::ACCESS_16BIT; - case PAS::ACCESS_32BIT: - return LAS::ACCESS_32BIT; - } - - return LAS::ACCESS_8BIT; -} - - -template -static void apply(Platform::Device const &device, - Xml_node const &devices, - FN const &fn) -{ - using namespace Genode; - using N = Platform::Device::Name; - - auto lookup_device = [&] (Xml_node const &node) { - if (node.attribute_value("name", N()) == device.name()) - fn(node); - }; - - devices.for_each_sub_node("device", lookup_device); -} - - -static unsigned bar_size(Platform::Device const &dev, - Xml_node const &devices, unsigned bar) -{ - if (bar > 6) - return 0; - - using namespace Genode; - - unsigned val = 0; - apply(dev, devices, [&] (Xml_node device) { - device.for_each_sub_node("io_mem", [&] (Xml_node node) { - if (node.attribute_value("bar", 6u) != bar) - return; - - val = node.attribute_value("size", 0u); - }); - - device.for_each_sub_node("io_port", [&] (Xml_node node) { - if (node.attribute_value("bar", 6u) != bar) - return; - - val = node.attribute_value("size", 0u); - }); - }); - - return val; -} - - -static unsigned bar_address(Platform::Device const &dev, - Xml_node const &devices, unsigned bar) -{ - if (bar > 6) - return 0; - - using namespace Genode; - - unsigned val = 0; - apply(dev, devices, [&] (Xml_node device) { - device.for_each_sub_node("io_mem", [&] (Xml_node node) { - if (node.attribute_value("bar", 6u) != bar) - return; - - val = node.attribute_value("phys_addr", 0u); - }); - - device.for_each_sub_node("io_port", [&] (Xml_node node) { - if (node.attribute_value("bar", 6u) != bar) - return; - - val = node.attribute_value("phys_addr", 0u); - }); - }); - - return val; -} - - -static unsigned char irq_line(Platform::Device const &dev, - Xml_node const &devices) -{ - enum : unsigned char { INVALID_IRQ_LINE = 0xffu }; - unsigned char irq = INVALID_IRQ_LINE; - - apply(dev, devices, [&] (Xml_node device) { - device.for_each_sub_node("irq", [&] (Xml_node node) { - irq = node.attribute_value("number", (unsigned char)INVALID_IRQ_LINE); - }); - }); - - return irq; -} - - -Platform::Device::Device(Connection &platform, Type) -: _platform { platform } { } - - -Platform::Device::Device(Connection &platform, Name name) -: - _platform { platform }, - _device_cap { _platform.device_cap(name.string()) }, - _name { name } -{ - if (!_device_cap.valid()) { - error(__func__, ": could not get device capability"); - throw -1; - } - - Legacy_platform::Device_client device(_device_cap); - _class_code = device.class_code() >> 8; -} - - -unsigned Platform::Device::Config_space::read(unsigned char address, - Access_size size) -{ - /* 32bit BARs only for now */ - if (address >= 0x10 && address <= 0x24) { - unsigned const bar = (address - 0x10) / 4; - if (_device._bar_checked_for_size[bar]) { - _device._bar_checked_for_size[bar] = 0; - return bar_size(_device, *_device._platform._devices_node, bar); - } - - return bar_address(_device, *_device._platform._devices_node, bar); - } - - /* - * If any PCI device reports 0 as interrupt PIN, drivers may try to force - * MSI setup (e.g., xhci). So, we clamp the interrupt PIN to 1 to let - * drivers finish initialization and don't bother the platform driver. - */ - if (address == 0x3d) - return 0x01; - - if (address == 0x3c) - return irq_line(_device, *_device._platform._devices_node); - - if (address == 0x34) - return 0u; - - Legacy_platform::Device::Access_size const as = convert(size); - Legacy_platform::Device_client device { _device._device_cap }; - return device.config_read(address, as); -} - - -void Platform::Device::Config_space::write(unsigned char address, - unsigned value, - Access_size size) -{ - /* 32bit BARs only for now */ - if (address >= 0x10 && address <= 0x24) { - unsigned const bar = (address - 0x10) / 4; - if (value == 0xffffffffu) - _device._bar_checked_for_size[bar] = 1; - return; - } - - enum { - CLASS_CODE_USB = 0xc03, - }; - - switch(_device._class_code) { - case CLASS_CODE_USB: - /* reject writes to unknown addresses */ - switch (address) { - case 0x04: - /* - * Doing this multiple times induces multiple "assignment of PCI - * device" diasgnostics currently. - */ - /* command register (value for enable io, memory, bus master) */ - value = 7; - break; - - /* - * Write in [0x40,0xff] should be okay if there are is no capability - * list (status register bit 4 + capability list pointer). Otherwise, - * writes into capability-list entries should be rejected. - */ - - case 0xc0: /* UHCI BIOS handoff (UHCI_USBLEGSUP) */ break; - case 0xc4: /* UHCI INTEL resume-enable (USBRES_INTEL) */ break; - case 0x60 ... 0x6f: /* EHCI BIOS handoff (just empiric, address not fixed) */ break; - - default: - return; - } - break; - } - - Legacy_platform::Device::Access_size const as = convert(size); - Legacy_platform::Device_client device { _device._device_cap }; - device.config_write(address, value, as); -} - - -size_t Platform::Device::Mmio::size() const -{ - return _attached_ds.constructed() ? _attached_ds->size() : 0; -} - - -void *Platform::Device::Mmio::_local_addr() -{ - if (!_attached_ds.constructed()) { - Legacy_platform::Device_client device { _device._device_cap }; - - Cache cache = Cache::UNCACHED; - - { - uint8_t phys_bar_id = 0; - - /* convert virtual bar id into phys bar id */ - for (unsigned virt_id = 0, i = 0; i < 6; i++) { - auto const type = device.resource(i).type(); - if (type == Legacy_platform::Device::Resource::Type::MEMORY) { - virt_id ++; - phys_bar_id = uint8_t(i); - } - if (virt_id > _index.value) - break; - } - - 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 = - device.io_mem(uint8_t(_index.value), cache); - - Io_mem_session_client io_mem_client(io_mem_cap); - - _attached_ds.construct(Lx_kit::env().env.rm(), - io_mem_client.dataspace()); - } - - return (void*)(_attached_ds->local_addr() + Range::start); -} - - -Platform::Device::Io_port_range::Io_port_range(Device &device, Index index) -: - _device { device }, - _index { index } -{ - Legacy_platform::Device_client client { _device._device_cap }; - - _io_port.construct(client.io_port((uint8_t)index.value)); -} - - -unsigned char Platform::Device::Io_port_range::inb(uint16_t addr) -{ - return _io_port->inb(addr); -} - - -unsigned short Platform::Device::Io_port_range::inw(uint16_t addr) -{ - return _io_port->inw(addr); -} - - -unsigned int Platform::Device::Io_port_range::inl(uint16_t addr) -{ - return _io_port->inl(addr); -} - - -void Platform::Device::Io_port_range::outb(uint16_t addr, uint8_t val) -{ - return _io_port->outb(addr, val); -} - - -void Platform::Device::Io_port_range::outw(uint16_t addr, uint16_t val) -{ - return _io_port->outw(addr, val); -} - - -void Platform::Device::Io_port_range::outl(uint16_t addr, uint32_t val) -{ - return _io_port->outl(addr, val); -} - - -Platform::Device::Irq::Irq(Platform::Device &device, Index index) -: - _device { device }, - _index { index } -{ - Legacy_platform::Device_client client { _device._device_cap }; - - _irq.construct(client.irq((uint8_t)index.value)); -} - -void Platform::Device::Irq::ack() -{ - _irq->ack_irq(); -} - - -void Platform::Device::Irq::sigh(Signal_context_capability sigh) -{ - _irq->sigh(sigh); - _irq->ack_irq(); -} - - -void Platform::Device::Irq::sigh_omit_initial_signal(Signal_context_capability sigh) -{ - _irq->sigh(sigh); -} - - -static Platform::Device::Config_space::Access_size access_size(unsigned len) -{ - using AS = Platform::Device::Config_space::Access_size; - AS as = AS::ACCESS_8BIT; - if (len == 4) as = AS::ACCESS_32BIT; - else if (len == 2) as = AS::ACCESS_16BIT; - else as = AS::ACCESS_8BIT; - - return as; -} - - -bool Lx_kit::Device::read_config(unsigned reg, unsigned len, unsigned *val) -{ - if (!_pdev.constructed()) - enable(); - - if (!val) - return false; - - using AS = Platform::Device::Config_space::Access_size; - AS const as = access_size(len); - - *val = Platform::Device::Config_space(*_pdev).read((unsigned char)reg, as); - return true; -} - - -bool Lx_kit::Device::write_config(unsigned reg, unsigned len, unsigned val) -{ - if (!_pdev.constructed()) - return false; - - using AS = Platform::Device::Config_space::Access_size; - AS const as = access_size(len); - - Platform::Device::Config_space(*_pdev).write((unsigned char)reg, val, as); - return true; -} diff --git a/repos/pc/lib/import/import-pc_lx_emul.mk b/repos/pc/lib/import/import-pc_lx_emul.mk index 5f9b724e7f..55ab8d47ea 100644 --- a/repos/pc/lib/import/import-pc_lx_emul.mk +++ b/repos/pc/lib/import/import-pc_lx_emul.mk @@ -25,11 +25,16 @@ SRC_C += lx_emul/shadow/lib/devres.c SRC_C += lx_emul/shadow/lib/smp_processor_id.c SRC_C += lx_emul/shadow/mm/memblock.c SRC_C += lx_emul/shadow/mm/page_alloc.c -SRC_CC += lx_emul/pci_config_space.cc -SRC_CC += lx_emul/pci_init.cc +SRC_C += lx_emul/shadow/drivers/pci/host-bridge.c +SRC_C += lx_emul/shadow/drivers/pci/pci.c +SRC_C += lx_emul/shadow/drivers/pci/pci-sysfs.c +SRC_C += lx_emul/shadow/drivers/pci/search.c +SRC_C += lx_emul/shadow/drivers/pci/setup-irq.c +SRC_C += lx_emul/shadow/drivers/pci/setup-res.c +SRC_CC += lx_emul/pci.cc +SRC_CC += lx_emul/pci_bus.c SRC_CC += lx_kit/device.cc SRC_CC += lx_kit/memory_dma.cc -SRC_CC += lx_kit/spec/x86/platform.cc SRC_C += lx_emul/shadow/fs/sysfs/dir.c SRC_C += lx_emul/shadow/fs/sysfs/file.c diff --git a/repos/pc/lib/mk/wifi.inc b/repos/pc/lib/mk/wifi.inc index 1510384a19..54583be571 100644 --- a/repos/pc/lib/mk/wifi.inc +++ b/repos/pc/lib/mk/wifi.inc @@ -25,7 +25,6 @@ SRC_C += lx_socket_call.c SRC_C += $(notdir $(wildcard $(TARGET_LIB_DIR)/generated_dummies.c)) SRC_C += lx_emul/common_dummies.c -SRC_C += lx_emul/spec/x86/pci.c CC_C_OPT += -I$(LX_SRC_DIR)/drivers/net/wireless/intel/iwlwifi CC_C_OPT += -I$(LX_SRC_DIR)/include/linux diff --git a/repos/pc/recipes/api/pc_linux/content.mk b/repos/pc/recipes/api/pc_linux/content.mk index 3f5fd64d3a..690b3cc7f9 100644 --- a/repos/pc/recipes/api/pc_linux/content.mk +++ b/repos/pc/recipes/api/pc_linux/content.mk @@ -2,6 +2,10 @@ # Content hosted in the dde_linux repository # +content: include/pci +include/pci: + mkdir -p $(dir $@); cp -r $(GENODE_DIR)/repos/os/$@ $(dir $@) + MIRRORED_FROM_DDE_LINUX := src/lib/lx_emul \ src/lib/lx_kit \ src/include/lx_emul \ diff --git a/repos/pc/recipes/pkg/test_usb_host_drv-pc/archives b/repos/pc/recipes/pkg/test_usb_host_drv-pc/archives index 77ea7d26a7..373005556b 100644 --- a/repos/pc/recipes/pkg/test_usb_host_drv-pc/archives +++ b/repos/pc/recipes/pkg/test_usb_host_drv-pc/archives @@ -1,5 +1,6 @@ _/raw/test_usb_host_drv-pc _/src/acpi_drv +_/src/pci_decode _/src/pc_usb_host_drv _/src/platform_drv _/src/report_rom diff --git a/repos/pc/recipes/raw/test_usb_host_drv-pc/drivers.config b/repos/pc/recipes/raw/test_usb_host_drv-pc/drivers.config index 44e481bd46..08b2fbe9b4 100644 --- a/repos/pc/recipes/raw/test_usb_host_drv-pc/drivers.config +++ b/repos/pc/recipes/raw/test_usb_host_drv-pc/drivers.config @@ -15,6 +15,24 @@ + + + + + + + + + + + + + + + + + + @@ -28,33 +46,27 @@ - + - - - - - - - - - - - + + + + + + + + + + - - - - - - - + + + - - + @@ -65,11 +77,11 @@ - + - + diff --git a/repos/pc/run/intel_fb.run b/repos/pc/run/intel_fb.run index bcae18868a..83a5098c12 100644 --- a/repos/pc/run/intel_fb.run +++ b/repos/pc/run/intel_fb.run @@ -19,6 +19,9 @@ set use_top 0 set build_components { core init timer + drivers/acpi + drivers/platform + app/pci_decode drivers/framebuffer/intel/pc test/framebuffer server/report_rom @@ -31,9 +34,6 @@ set build_components { append_if $use_gpu build_components { drivers/gpu/intel } append_if $use_top build_components { app/top } -source ${genode_dir}/repos/base/run/platform_drv.inc -append_platform_drv_build_components - build $build_components create_boot_directory @@ -58,22 +58,86 @@ append config { - } + -append_platform_drv_config + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -append config { - - - - - - @@ -81,7 +145,7 @@ append config { - + @@ -221,13 +285,12 @@ install_config $config set boot_modules { core ld.lib.so init timer pc_intel_fb_drv intel_fb_controller test-framebuffer report_rom fs_rom vfs vfs.lib.so vfs_import.lib.so + platform_drv acpi_drv pci_decode } append_if $use_gpu boot_modules { intel_gpu_drv } append_if $use_top boot_modules { top } -append_platform_drv_boot_modules - build_boot_image $boot_modules if { [get_cmd_switch --autopilot] } { diff --git a/repos/pc/run/wifi.run b/repos/pc/run/wifi.run index 2e87c25e43..ef5df2b717 100644 --- a/repos/pc/run/wifi.run +++ b/repos/pc/run/wifi.run @@ -65,6 +65,9 @@ assert_spec x86 set build_components { core init timer + app/pci_decode + drivers/acpi + drivers/platform drivers/rtc drivers/wifi/pc server/report_rom @@ -76,9 +79,6 @@ set build_components { lib/vfs_lwip } -source ${genode_dir}/repos/base/run/platform_drv.inc -append_platform_drv_build_components - build $build_components create_boot_directory @@ -108,6 +108,73 @@ append config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -227,11 +294,6 @@ append config { -} - -append_platform_drv_config - -append config { } @@ -267,15 +329,13 @@ set boot_modules { wpa_driver_nl80211.lib.so wpa_supplicant.lib.so pc_wifi_drv wifi.lib.so vfs_wifi.lib.so nic_router - + platform_drv acpi_drv pci_decode test-lwip_httpsrv vfs_lwip.lib.so } append boot_modules $firmware_modules -append_platform_drv_boot_modules - build_boot_image $boot_modules run_genode_until forever diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/dummies.c b/repos/pc/src/drivers/framebuffer/intel/pc/dummies.c index c3d5c16d12..2dcdda40a9 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/dummies.c +++ b/repos/pc/src/drivers/framebuffer/intel/pc/dummies.c @@ -547,3 +547,33 @@ int wbinvd_on_all_cpus(void) lx_emul_trace(__func__); return 0; } + + +void srcu_drive_gp(struct work_struct *wp); +void srcu_drive_gp(struct work_struct *wp) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int pci_bus_read_config_byte(struct pci_bus *bus, unsigned int devfn, + int where, u8 *val) +{ + lx_emul_trace_and_stop(__func__); +} + + +int pci_bus_read_config_word(struct pci_bus *bus, unsigned int devfn, + int where, u16 *val) +{ + lx_emul_trace_and_stop(__func__); +} + + +int pci_bus_write_config_byte(struct pci_bus *bus, unsigned int devfn, + int where, u8 val) +{ + lx_emul_trace_and_stop(__func__); +} diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/emul.cc b/repos/pc/src/drivers/framebuffer/intel/pc/emul.cc index 243f0a6501..0baedcea44 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/emul.cc +++ b/repos/pc/src/drivers/framebuffer/intel/pc/emul.cc @@ -29,3 +29,22 @@ void emul_free_shmem_file_buffer(void *addr) { Lx_kit::env().memory.free_buffer(addr); } + + +unsigned short emul_intel_gmch_control_reg() +{ + using namespace Genode; + + unsigned short ret = 0; + Lx_kit::env().devices.with_xml([&] (Xml_node node) { + node.for_each_sub_node("device", [&] (Xml_node node) { + node.for_each_sub_node("pci-config", [&] (Xml_node node) { + unsigned short gmch = + node.attribute_value("intel_gmch_control", 0U); + if (gmch) ret = gmch; + }); + }); + }); + + return ret; +} diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/generated_dummies.c b/repos/pc/src/drivers/framebuffer/intel/pc/generated_dummies.c index e6c1c56582..805a441ff3 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/generated_dummies.c +++ b/repos/pc/src/drivers/framebuffer/intel/pc/generated_dummies.c @@ -1,7 +1,7 @@ /* * \brief Dummy definitions of Linux Kernel functions * \author Automatically generated file - do no edit - * \date 2022-06-24 + * \date 2022-07-28 */ #include @@ -1525,14 +1525,6 @@ void mark_page_accessed(struct page * page) } -#include - -unsigned long long memparse(const char * ptr,char ** retptr) -{ - lx_emul_trace_and_stop(__func__); -} - - #include void memunmap(void * addr) @@ -1646,7 +1638,7 @@ enum reboot_mode panic_reboot_mode; #include -void pci_assign_unassigned_bridge_resources(struct pci_dev * bridge) +int pci_dev_present(const struct pci_device_id * ids) { lx_emul_trace_and_stop(__func__); } @@ -1654,14 +1646,7 @@ void pci_assign_unassigned_bridge_resources(struct pci_dev * bridge) #include -void pci_assign_unassigned_bus_resources(struct pci_bus * bus) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern unsigned long pci_cardbus_resource_alignment(struct resource * res); -unsigned long pci_cardbus_resource_alignment(struct resource * res) +void pci_disable_device(struct pci_dev * dev) { lx_emul_trace_and_stop(__func__); } @@ -1669,11 +1654,7 @@ unsigned long pci_cardbus_resource_alignment(struct resource * res) #include -unsigned int pci_flags; - - -extern int pci_idt_bus_quirk(struct pci_bus * bus,int devfn,u32 * l,int timeout); -int pci_idt_bus_quirk(struct pci_bus * bus,int devfn,u32 * l,int timeout) +int pci_read_config_byte(const struct pci_dev * dev,int where,u8 * val) { lx_emul_trace_and_stop(__func__); } @@ -1681,28 +1662,7 @@ int pci_idt_bus_quirk(struct pci_bus * bus,int devfn,u32 * l,int timeout) #include -int pci_mmap_resource_range(struct pci_dev * pdev,int bar,struct vm_area_struct * vma,enum pci_mmap_state mmap_state,int write_combine) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void __init pci_realloc_get_opt(char * str); -void __init pci_realloc_get_opt(char * str) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void pci_restore_vc_state(struct pci_dev * dev); -void pci_restore_vc_state(struct pci_dev * dev) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern int pci_save_vc_state(struct pci_dev * dev); -int pci_save_vc_state(struct pci_dev * dev) +int pci_save_state(struct pci_dev * dev) { lx_emul_trace_and_stop(__func__); } @@ -1710,42 +1670,23 @@ int pci_save_vc_state(struct pci_dev * dev) #include -void pci_stop_and_remove_bus_device_locked(struct pci_dev * dev) +int pci_set_power_state(struct pci_dev * dev,pci_power_t state) { lx_emul_trace_and_stop(__func__); } -extern void pci_vpd_release(struct pci_dev * dev); -void pci_vpd_release(struct pci_dev * dev) +#include + +void pci_unmap_rom(struct pci_dev * pdev,void __iomem * rom) { lx_emul_trace_and_stop(__func__); } -extern unsigned int pcibios_assign_all_busses(void); -unsigned int pcibios_assign_all_busses(void) -{ - lx_emul_trace_and_stop(__func__); -} +#include - -extern void pcie_aspm_init_link_state(struct pci_dev * pdev); -void pcie_aspm_init_link_state(struct pci_dev * pdev) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void pcie_aspm_pm_state_change(struct pci_dev * pdev); -void pcie_aspm_pm_state_change(struct pci_dev * pdev) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void pcie_aspm_powersave_config_link(struct pci_dev * pdev); -void pcie_aspm_powersave_config_link(struct pci_dev * pdev) +int pci_write_config_byte(const struct pci_dev * dev,int where,u8 val) { lx_emul_trace_and_stop(__func__); } @@ -1789,14 +1730,6 @@ void put_pid(struct pid * pid) } -#include - -int raw_pci_read(unsigned int domain,unsigned int bus,unsigned int devfn,int reg,int len,u32 * val) -{ - lx_emul_trace_and_stop(__func__); -} - - #include enum reboot_mode reboot_mode; @@ -1899,7 +1832,7 @@ void * skb_put(struct sk_buff * skb,unsigned int len) #include -int smp_call_function_single(int cpu,void (* func)(void * info),void * info,int wait) +int smp_call_function_single(int cpu,smp_call_func_t func,void * info,int wait) { lx_emul_trace_and_stop(__func__); } @@ -2016,3 +1949,4 @@ void wake_q_add_safe(struct wake_q_head * head,struct task_struct * task) { lx_emul_trace_and_stop(__func__); } + diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/lx_emul.h b/repos/pc/src/drivers/framebuffer/intel/pc/lx_emul.h index 7dc6902aa1..aa6eb2c74e 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/lx_emul.h +++ b/repos/pc/src/drivers/framebuffer/intel/pc/lx_emul.h @@ -28,21 +28,16 @@ struct dma_fence_work_ops; void lx_emul_time_udelay(unsigned long usec); -/* shadow/asm/io.h */ -void lx_emul_io_port_outb(unsigned char value, unsigned short port); -void lx_emul_io_port_outw(unsigned short value, unsigned short port); -void lx_emul_io_port_outl(unsigned int value, unsigned short port); - -unsigned char lx_emul_io_port_inb(unsigned short port); -unsigned short lx_emul_io_port_inw(unsigned short port); -unsigned int lx_emul_io_port_inl(unsigned short port); - void *emul_alloc_shmem_file_buffer(unsigned long); void * intel_io_mem_map(unsigned long offset, unsigned long size); #include "lx_i915.h" +unsigned short emul_intel_gmch_control_reg(void); + +enum { OPREGION_PSEUDO_PHYS_ADDR = 0xffffefff }; + #ifdef __cplusplus } #endif diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/misc.cc b/repos/pc/src/drivers/framebuffer/intel/pc/misc.cc deleted file mode 100644 index 73f6e67174..0000000000 --- a/repos/pc/src/drivers/framebuffer/intel/pc/misc.cc +++ /dev/null @@ -1,20 +0,0 @@ -/* - * \brief Misc - * \author Josef Soentgen - * \date 2022-01-20 - */ - -/* - * Copyright (C) 2022 Genode Labs GmbH - * - * This file is distributed under the terms of the GNU General Public License - * version 2. - */ - -/* Genode includes */ -#include - -extern "C" void lx_backtrace(void) -{ - Genode::backtrace(); -} diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/opregion_io_mem.cc b/repos/pc/src/drivers/framebuffer/intel/pc/opregion_io_mem.cc index b97e7d56d5..3271d51f16 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/opregion_io_mem.cc +++ b/repos/pc/src/drivers/framebuffer/intel/pc/opregion_io_mem.cc @@ -21,6 +21,7 @@ #include #include +#include extern "C" void * intel_io_mem_map(unsigned long const phys, unsigned long const size) @@ -51,12 +52,16 @@ extern "C" void * intel_io_mem_map(unsigned long const phys, } } - if ((opregion_start <= phys) && - (phys + size <= opregion_start + opregion_size)) { + /* + * we have to substract the pseudo physical address + * we returned when reading the ASLS from config space + */ + addr_t offset = phys - OPREGION_PSEUDO_PHYS_ADDR; + if ((offset + size) <= opregion_size) { try { auto ptr = ((addr_t)rom_opregion->local_addr()) - + (phys - opregion_start) + (phys & 0xffful); + + offset + (opregion_start & 0xffful); return (void *)ptr; } catch (...) { error("Intel opregion lookup failed"); diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/pci.c b/repos/pc/src/drivers/framebuffer/intel/pc/pci.c new file mode 100644 index 0000000000..883e1c0795 --- /dev/null +++ b/repos/pc/src/drivers/framebuffer/intel/pc/pci.c @@ -0,0 +1,140 @@ +/* + * \brief Additional PCI functions needed by Intel graphics driver + * \author Stefan Kalkowski + * \author Josef Soentgen + * \date 2022-07-27 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#include +#include +#include + +#include +#include +#include <../drivers/gpu/drm/i915/i915_reg.h> +#undef GFX_FLSH_CNTL /* suppress warning of double define */ +#include <../drivers/char/agp/intel-agp.h> + + +unsigned long pci_mem_start = 0xaeedbabe; + + +int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, + resource_size_t size, resource_size_t align, + resource_size_t min, unsigned long type_mask, + resource_size_t (*alignf)(void *, + const struct resource *, + resource_size_t, + resource_size_t), + void *alignf_data) +{ + return -1; +} + + +void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) +{ + struct resource *r; + unsigned long phys_addr; + unsigned long size; + + if (!dev || bar > 5) { + printk("%s:%d: invalid request for dev: %p bar: %d\n", + __func__, __LINE__, dev, bar); + return NULL; + } + + printk("pci_iomap: request for dev: %s bar: %d\n", dev_name(&dev->dev), bar); + + r = &dev->resource[bar]; + + phys_addr = r->start; + size = r->end - r->start; + + if (!phys_addr || !size) + return NULL; + + return lx_emul_io_mem_map(phys_addr, size); +} + + +void __iomem * pci_map_rom(struct pci_dev * pdev,size_t * size) +{ + /* + * Needed for VBT access which we do not allow + */ + return NULL; +} + + +int pci_read_config_word(const struct pci_dev * dev, int where, u16 *val) +{ + switch (where) { + /* Intel graphics and memory controller hub control register */ + /* I830_GMCH_CTRL is identical to INTEL_GMCH_CTRL */ + case SNB_GMCH_CTRL: + case INTEL_GMCH_CTRL: + *val = emul_intel_gmch_control_reg(); + return 0; + case SWSCI: /* intel_fb: software smi sci */ + *val = 0; + return 0; + }; + + printk("%s: %s %d %d\n", __func__, dev_name(&dev->dev), dev->devfn, where); + lx_emul_trace_and_stop(__func__); +} + + +int pci_read_config_dword(const struct pci_dev * dev, int where, u32 *val) +{ + switch (where) { + case MCHBAR_I915: + case MCHBAR_I965: + *val = 0x1; /* return ENABLE bit being set */ + return 0; + case I965_IFPADDR: /* intel host bridge flush page (lower) */ + case I965_IFPADDR + 4: /* intel host bridge flush page (higher) */ + *val = 0; + return 0; + case ASLS: + /* + * we just use a physical address as token here, + * hopefully it never crashes with other I/O memory addresses + */ + *val = OPREGION_PSEUDO_PHYS_ADDR; + return 0; + }; + + lx_emul_trace_and_stop(__func__); +} + + +int pci_write_config_word(const struct pci_dev * dev, int where, u16 val) +{ + switch (where) { + case SWSCI: /* intel_fb: software smi sci */ + /* just ignore */ + return 0; + }; + lx_emul_trace_and_stop(__func__); +} + + +int pci_write_config_dword(const struct pci_dev * dev, int where, u32 val) +{ + switch (where) { + case I965_IFPADDR: /* intel host bridge flush page (lower) */ + case I965_IFPADDR + 4: /* intel host bridge flush page (higher) */ + /* just ignore */ + return 0; + }; + lx_emul_trace_and_stop(__func__); +} diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/spec/x86_32/source.list b/repos/pc/src/drivers/framebuffer/intel/pc/spec/x86_32/source.list index 0e717db882..5935c1e143 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/spec/x86_32/source.list +++ b/repos/pc/src/drivers/framebuffer/intel/pc/spec/x86_32/source.list @@ -1,5 +1,4 @@ arch/x86/lib/hweight.S -arch/x86/pci/legacy.c arch/x86/platform/intel/iosf_mbi.c drivers/base/bus.c drivers/base/class.c @@ -183,19 +182,7 @@ drivers/i2c/algos/i2c-algo-bit.c drivers/i2c/i2c-boardinfo.c drivers/i2c/i2c-core-acpi.c drivers/i2c/i2c-core-base.c -drivers/pci/access.c -drivers/pci/bus.c -drivers/pci/host-bridge.c -drivers/pci/msi.c drivers/pci/pci-driver.c -drivers/pci/pci-label.c -drivers/pci/pci-sysfs.c -drivers/pci/pci.c -drivers/pci/probe.c -drivers/pci/rom.c -drivers/pci/search.c -drivers/pci/setup-res.c -drivers/pci/slot.c drivers/video/backlight/backlight.c drivers/video/fbdev/core/fb_notify.c drivers/video/fbdev/core/fbcmap.c @@ -257,7 +244,6 @@ lib/kstrtox.c lib/list_sort.c lib/llist.c lib/math/div64.c -lib/pci_iomap.c lib/radix-tree.c lib/rbtree.c lib/refcount.c diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/spec/x86_64/source.list b/repos/pc/src/drivers/framebuffer/intel/pc/spec/x86_64/source.list index abdcec0de1..a0e3aabad9 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/spec/x86_64/source.list +++ b/repos/pc/src/drivers/framebuffer/intel/pc/spec/x86_64/source.list @@ -2,7 +2,6 @@ arch/x86/lib/hweight.S arch/x86/lib/memcpy_64.S arch/x86/lib/memmove_64.S arch/x86/lib/memset_64.S -arch/x86/pci/legacy.c arch/x86/platform/intel/iosf_mbi.c drivers/base/bus.c drivers/base/class.c @@ -186,19 +185,7 @@ drivers/i2c/algos/i2c-algo-bit.c drivers/i2c/i2c-boardinfo.c drivers/i2c/i2c-core-acpi.c drivers/i2c/i2c-core-base.c -drivers/pci/access.c -drivers/pci/bus.c -drivers/pci/host-bridge.c -drivers/pci/msi.c drivers/pci/pci-driver.c -drivers/pci/pci-label.c -drivers/pci/pci-sysfs.c -drivers/pci/pci.c -drivers/pci/probe.c -drivers/pci/rom.c -drivers/pci/search.c -drivers/pci/setup-res.c -drivers/pci/slot.c drivers/video/backlight/backlight.c drivers/video/fbdev/core/fb_notify.c drivers/video/fbdev/core/fbcmap.c @@ -259,7 +246,6 @@ lib/kobject_uevent.c lib/kstrtox.c lib/list_sort.c lib/llist.c -lib/pci_iomap.c lib/radix-tree.c lib/rbtree.c lib/refcount.c diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/target.inc b/repos/pc/src/drivers/framebuffer/intel/pc/target.inc index 5a50f3cf6e..e9d62979af 100644 --- a/repos/pc/src/drivers/framebuffer/intel/pc/target.inc +++ b/repos/pc/src/drivers/framebuffer/intel/pc/target.inc @@ -9,21 +9,21 @@ INC_DIR += $(REL_PRG_DIR) INC_DIR += $(REL_PRG_DIR)/shadow SRC_CC += main.cc -SRC_CC += misc.cc SRC_CC += emul.cc SRC_CC += time.cc SRC_CC += opregion_io_mem.cc SRC_C += dummies.c +SRC_C += pci.c SRC_C += lx_emul.c SRC_C += $(notdir $(wildcard $(REL_PRG_DIR)/generated_dummies.c)) SRC_C += fb.c SRC_C += lx_user.c SRC_C += gem.c SRC_C += lx_emul/common_dummies.c -SRC_C += lx_emul/spec/x86/pci.c SRC_C += lx_emul/shadow/mm/page_alloc.c +SRC_C += lx_emul/shadow/drivers/char/random.c -vpath %.c $(REL_PRG_DIR) +vpath %.c $(REL_PRG_DIR) vpath %.cc $(REL_PRG_DIR) vpath %.c $(REP_DIR)/src/lib/pc diff --git a/repos/pc/src/drivers/usb_host/pc/dummies.c b/repos/pc/src/drivers/usb_host/pc/dummies.c index 66714bec4d..6b4d44448d 100644 --- a/repos/pc/src/drivers/usb_host/pc/dummies.c +++ b/repos/pc/src/drivers/usb_host/pc/dummies.c @@ -90,3 +90,11 @@ u32 prandom_u32(void) { lx_emul_trace_and_stop(__func__); } + + +#include + +void pci_disable_device(struct pci_dev * dev) +{ + lx_emul_trace(__func__); +} diff --git a/repos/pc/src/drivers/usb_host/pc/generated_dummies.c b/repos/pc/src/drivers/usb_host/pc/generated_dummies.c index 2befa28591..c26547801b 100644 --- a/repos/pc/src/drivers/usb_host/pc/generated_dummies.c +++ b/repos/pc/src/drivers/usb_host/pc/generated_dummies.c @@ -1,7 +1,7 @@ /* * \brief Dummy definitions of Linux Kernel functions * \author Automatically generated file - do no edit - * \date 2022-05-06 + * \date 2022-07-29 */ #include @@ -301,14 +301,6 @@ int kobject_uevent_env(struct kobject * kobj,enum kobject_action action,char * e } -#include - -unsigned long long memparse(const char * ptr,char ** retptr) -{ - lx_emul_trace_and_stop(__func__); -} - - #include struct irq_chip no_irq_chip; @@ -348,7 +340,7 @@ int param_set_copystring(const char * val,const struct kernel_param * kp) #include -void pci_assign_unassigned_bridge_resources(struct pci_dev * bridge) +void pci_clear_mwi(struct pci_dev * dev) { lx_emul_trace_and_stop(__func__); } @@ -356,14 +348,7 @@ void pci_assign_unassigned_bridge_resources(struct pci_dev * bridge) #include -void pci_assign_unassigned_bus_resources(struct pci_bus * bus) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern unsigned long pci_cardbus_resource_alignment(struct resource * res); -unsigned long pci_cardbus_resource_alignment(struct resource * res) +struct pci_dev * pci_get_slot(struct pci_bus * bus,unsigned int devfn) { lx_emul_trace_and_stop(__func__); } @@ -371,11 +356,7 @@ unsigned long pci_cardbus_resource_alignment(struct resource * res) #include -unsigned int pci_flags; - - -extern int pci_idt_bus_quirk(struct pci_bus * bus,int devfn,u32 * l,int timeout); -int pci_idt_bus_quirk(struct pci_bus * bus,int devfn,u32 * l,int timeout) +int pci_set_power_state(struct pci_dev * dev,pci_power_t state) { lx_emul_trace_and_stop(__func__); } @@ -383,71 +364,7 @@ int pci_idt_bus_quirk(struct pci_bus * bus,int devfn,u32 * l,int timeout) #include -int pci_mmap_resource_range(struct pci_dev * pdev,int bar,struct vm_area_struct * vma,enum pci_mmap_state mmap_state,int write_combine) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void __init pci_realloc_get_opt(char * str); -void __init pci_realloc_get_opt(char * str) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void pci_restore_vc_state(struct pci_dev * dev); -void pci_restore_vc_state(struct pci_dev * dev) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern int pci_save_vc_state(struct pci_dev * dev); -int pci_save_vc_state(struct pci_dev * dev) -{ - lx_emul_trace_and_stop(__func__); -} - - -#include - -void pci_stop_and_remove_bus_device_locked(struct pci_dev * dev) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void pci_vpd_release(struct pci_dev * dev); -void pci_vpd_release(struct pci_dev * dev) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern unsigned int pcibios_assign_all_busses(void); -unsigned int pcibios_assign_all_busses(void) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void pcie_aspm_init_link_state(struct pci_dev * pdev); -void pcie_aspm_init_link_state(struct pci_dev * pdev) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void pcie_aspm_pm_state_change(struct pci_dev * pdev); -void pcie_aspm_pm_state_change(struct pci_dev * pdev) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void pcie_aspm_powersave_config_link(struct pci_dev * pdev); -void pcie_aspm_powersave_config_link(struct pci_dev * pdev) +int pci_write_config_dword(const struct pci_dev * dev,int where,u32 val) { lx_emul_trace_and_stop(__func__); } @@ -469,14 +386,6 @@ void put_pid(struct pid * pid) } -#include - -int raw_pci_read(unsigned int domain,unsigned int bus,unsigned int devfn,int reg,int len,u32 * val) -{ - lx_emul_trace_and_stop(__func__); -} - - #include bool refcount_dec_not_one(refcount_t * r) @@ -511,7 +420,7 @@ void seq_printf(struct seq_file * m,const char * f,...) #include -int smp_call_function_single(int cpu,void (* func)(void * info),void * info,int wait) +int smp_call_function_single(int cpu,smp_call_func_t func,void * info,int wait) { lx_emul_trace_and_stop(__func__); } @@ -572,3 +481,4 @@ void wake_q_add_safe(struct wake_q_head * head,struct task_struct * task) { lx_emul_trace_and_stop(__func__); } + diff --git a/repos/pc/src/drivers/usb_host/pc/lx_emul.c b/repos/pc/src/drivers/usb_host/pc/lx_emul.c index a9b63c84ac..63c49b4c63 100644 --- a/repos/pc/src/drivers/usb_host/pc/lx_emul.c +++ b/repos/pc/src/drivers/usb_host/pc/lx_emul.c @@ -12,3 +12,76 @@ */ #include +#include + +void __iomem * pci_ioremap_bar(struct pci_dev * pdev, int bar) +{ + struct resource *res = &pdev->resource[bar]; + return ioremap(res->start, resource_size(res)); +} + + +enum { + UHCI_USBLEGSUP = 0xc0, + UHCI_USBRES_INTEL = 0xc4, + EHCI_SERIAL_BUS_RELEASE = 0x60, + EHCI_PORT_WAKE = 0x62, +}; + + +int pci_read_config_byte(const struct pci_dev * dev,int where,u8 * val) +{ + switch (where) { + case EHCI_SERIAL_BUS_RELEASE: + *val = 0x20; + return 0; + }; + lx_emul_trace_and_stop(__func__); +} + + +int pci_read_config_word(const struct pci_dev * dev,int where,u16 * val) +{ + switch (where) { + case PCI_COMMAND: + *val = 0x7; + return 0; + case EHCI_PORT_WAKE: + *val = 0; + return 0; + case UHCI_USBLEGSUP: + /* force the driver to do a full_reset */ + *val = 0xffff; + return 0; + }; + lx_emul_trace_and_stop(__func__); +} + + +int pci_read_config_dword(const struct pci_dev * dev,int where,u32 * val) +{ + *val = 0; + return 0; +} + + +int pci_write_config_byte(const struct pci_dev * dev,int where,u8 val) +{ + switch (where) { + case UHCI_USBRES_INTEL: + /* do nothing */ + return 0; + } + lx_emul_trace_and_stop(__func__); +} + + +int pci_write_config_word(const struct pci_dev * dev,int where,u16 val) +{ + switch (where) { + case UHCI_USBLEGSUP: + /* do nothing */ + return 0; + } + lx_emul_trace_and_stop(__func__); +} diff --git a/repos/pc/src/drivers/usb_host/pc/lx_emul.h b/repos/pc/src/drivers/usb_host/pc/lx_emul.h index fc240b2d77..2b25b75d96 100644 --- a/repos/pc/src/drivers/usb_host/pc/lx_emul.h +++ b/repos/pc/src/drivers/usb_host/pc/lx_emul.h @@ -24,8 +24,6 @@ extern "C" { #endif -void lx_backtrace(void); - void lx_emul_time_udelay(unsigned long usec); #ifdef __cplusplus diff --git a/repos/pc/src/drivers/usb_host/pc/spec/x86_32/source.list b/repos/pc/src/drivers/usb_host/pc/spec/x86_32/source.list index 1c750d29c8..510dc028d8 100644 --- a/repos/pc/src/drivers/usb_host/pc/spec/x86_32/source.list +++ b/repos/pc/src/drivers/usb_host/pc/spec/x86_32/source.list @@ -1,5 +1,4 @@ arch/x86/lib/hweight.S -arch/x86/pci/legacy.c drivers/base/bus.c drivers/base/class.c drivers/base/component.c @@ -10,18 +9,7 @@ drivers/base/driver.c drivers/base/platform.c drivers/base/property.c drivers/clk/clk-devres.c -drivers/pci/access.c -drivers/pci/bus.c -drivers/pci/host-bridge.c -drivers/pci/msi.c drivers/pci/pci-driver.c -drivers/pci/pci-sysfs.c -drivers/pci/pci.c -drivers/pci/probe.c -drivers/pci/rom.c -drivers/pci/search.c -drivers/pci/setup-res.c -drivers/pci/slot.c drivers/usb/common/common.c drivers/usb/common/debug.c drivers/usb/core/buffer.c @@ -110,7 +98,6 @@ lib/kobject.c lib/kstrtox.c lib/list_sort.c lib/math/div64.c -lib/pci_iomap.c lib/radix-tree.c lib/rbtree.c lib/scatterlist.c diff --git a/repos/pc/src/drivers/usb_host/pc/spec/x86_64/source.list b/repos/pc/src/drivers/usb_host/pc/spec/x86_64/source.list index 38d72247eb..bf4158e88b 100644 --- a/repos/pc/src/drivers/usb_host/pc/spec/x86_64/source.list +++ b/repos/pc/src/drivers/usb_host/pc/spec/x86_64/source.list @@ -1,5 +1,4 @@ arch/x86/lib/hweight.S -arch/x86/pci/legacy.c drivers/base/bus.c drivers/base/class.c drivers/base/component.c @@ -10,18 +9,7 @@ drivers/base/driver.c drivers/base/platform.c drivers/base/property.c drivers/clk/clk-devres.c -drivers/pci/access.c -drivers/pci/bus.c -drivers/pci/host-bridge.c -drivers/pci/msi.c drivers/pci/pci-driver.c -drivers/pci/pci-sysfs.c -drivers/pci/pci.c -drivers/pci/probe.c -drivers/pci/rom.c -drivers/pci/search.c -drivers/pci/setup-res.c -drivers/pci/slot.c drivers/usb/common/common.c drivers/usb/common/debug.c drivers/usb/core/buffer.c @@ -109,7 +97,6 @@ lib/klist.c lib/kobject.c lib/kstrtox.c lib/list_sort.c -lib/pci_iomap.c lib/radix-tree.c lib/rbtree.c lib/scatterlist.c diff --git a/repos/pc/src/drivers/usb_host/pc/target.inc b/repos/pc/src/drivers/usb_host/pc/target.inc index 1a6b805031..d9c11ce49e 100644 --- a/repos/pc/src/drivers/usb_host/pc/target.inc +++ b/repos/pc/src/drivers/usb_host/pc/target.inc @@ -7,15 +7,14 @@ LIBS := base pc_lx_emul jitterentropy INC_DIR += $(REL_PRG_DIR) SRC_CC += main.cc -SRC_CC += misc.cc SRC_CC += time.cc SRC_CC += lx_emul/shared_dma_buffer.cc SRC_C += dummies.c SRC_C += lx_emul.c SRC_C += $(notdir $(wildcard $(REL_PRG_DIR)/generated_dummies.c)) SRC_C += common_dummies.c -SRC_C += lx_emul/spec/x86/pci.c SRC_C += lx_emul/usb.c + SRC_C += lx_emul/shadow/lib/kobject_uevent.c vpath %.c $(REP_DIR)/src/lib/pc vpath %.cc $(REP_DIR)/src/lib/pc diff --git a/repos/pc/src/include/lx_emul/pci_fixups.h b/repos/pc/src/include/lx_emul/pci_fixups.h deleted file mode 100644 index 860d419eec..0000000000 --- a/repos/pc/src/include/lx_emul/pci_fixups.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * \brief PCI fixup calls to execute - * \author Josef Soentgen - * \date 2022-02-07 - */ - -/* - * Copyright (C) 2022 Genode Labs GmbH - * - * This file is distributed under the terms of the GNU General Public License - * version 2. - */ - -#ifndef _LX_EMUL__PCI_FIXUPS_H_ -#define _LX_EMUL__PCI_FIXUPS_H_ - -static const char * lx_emul_pci_final_fixups[] = { - "__pci_fixup_final_quirk_usb_early_handoff", - "END_OF_PCI_FIXUPS" -}; - -#endif /* _LX_EMUL__PCI_FIXUPS_H_ */ diff --git a/repos/pc/src/lib/wifi/dummies.c b/repos/pc/src/lib/wifi/dummies.c index 16fbf04a48..c77659d25d 100644 --- a/repos/pc/src/lib/wifi/dummies.c +++ b/repos/pc/src/lib/wifi/dummies.c @@ -244,6 +244,39 @@ bool pciehp_is_native(struct pci_dev *bridge) } +void pci_lock_rescan_remove(void) +{ + lx_emul_trace(__func__); +} + + +void pci_unlock_rescan_remove(void) +{ + lx_emul_trace(__func__); +} + + +bool pci_pme_capable(struct pci_dev *dev, pci_power_t state) +{ + lx_emul_trace(__func__); + return false; +} + + +int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val) +{ + lx_emul_trace(__func__); + return -1; +} + + +u16 pci_find_ext_capability(struct pci_dev *dev, int cap) +{ + lx_emul_trace(__func__); + return 0; +} + + #include struct thermal_cooling_device *thermal_cooling_device_register(const char *s, diff --git a/repos/pc/src/lib/wifi/generated_dummies.c b/repos/pc/src/lib/wifi/generated_dummies.c index 958ae3b0b2..384f9637a7 100644 --- a/repos/pc/src/lib/wifi/generated_dummies.c +++ b/repos/pc/src/lib/wifi/generated_dummies.c @@ -1,7 +1,7 @@ /* * \brief Dummy definitions of Linux Kernel functions * \author Automatically generated file - do no edit - * \date 2022-06-24 + * \date 2022-07-29 */ #include @@ -639,14 +639,6 @@ int kobject_synth_uevent(struct kobject * kobj,const char * buf,size_t count) } -#include - -unsigned long long memparse(const char * ptr,char ** retptr) -{ - lx_emul_trace_and_stop(__func__); -} - - #include void migrate_disable(void) @@ -712,63 +704,7 @@ enum reboot_mode panic_reboot_mode; #include -void pci_assign_unassigned_bridge_resources(struct pci_dev * bridge) -{ - lx_emul_trace_and_stop(__func__); -} - - -#include - -void pci_assign_unassigned_bus_resources(struct pci_bus * bus) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern unsigned long pci_cardbus_resource_alignment(struct resource * res); -unsigned long pci_cardbus_resource_alignment(struct resource * res) -{ - lx_emul_trace_and_stop(__func__); -} - - -#include - -unsigned int pci_flags; - - -extern int pci_idt_bus_quirk(struct pci_bus * bus,int devfn,u32 * l,int timeout); -int pci_idt_bus_quirk(struct pci_bus * bus,int devfn,u32 * l,int timeout) -{ - lx_emul_trace_and_stop(__func__); -} - - -#include - -int pci_mmap_resource_range(struct pci_dev * pdev,int bar,struct vm_area_struct * vma,enum pci_mmap_state mmap_state,int write_combine) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void __init pci_realloc_get_opt(char * str); -void __init pci_realloc_get_opt(char * str) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void pci_restore_vc_state(struct pci_dev * dev); -void pci_restore_vc_state(struct pci_dev * dev) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern int pci_save_vc_state(struct pci_dev * dev); -int pci_save_vc_state(struct pci_dev * dev) +int pci_read_config_dword(const struct pci_dev * dev,int where,u32 * val) { lx_emul_trace_and_stop(__func__); } @@ -784,42 +720,7 @@ void pci_stop_and_remove_bus_device(struct pci_dev * dev) #include -void pci_stop_and_remove_bus_device_locked(struct pci_dev * dev) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void pci_vpd_release(struct pci_dev * dev); -void pci_vpd_release(struct pci_dev * dev) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern unsigned int pcibios_assign_all_busses(void); -unsigned int pcibios_assign_all_busses(void) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void pcie_aspm_init_link_state(struct pci_dev * pdev); -void pcie_aspm_init_link_state(struct pci_dev * pdev) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void pcie_aspm_pm_state_change(struct pci_dev * pdev); -void pcie_aspm_pm_state_change(struct pci_dev * pdev) -{ - lx_emul_trace_and_stop(__func__); -} - - -extern void pcie_aspm_powersave_config_link(struct pci_dev * pdev); -void pcie_aspm_powersave_config_link(struct pci_dev * pdev) +int pci_write_config_word(const struct pci_dev * dev,int where,u16 val) { lx_emul_trace_and_stop(__func__); } @@ -889,14 +790,6 @@ void put_unused_fd(unsigned int fd) } -#include - -int raw_pci_read(unsigned int domain,unsigned int bus,unsigned int devfn,int reg,int len,u32 * val) -{ - lx_emul_trace_and_stop(__func__); -} - - #include enum reboot_mode reboot_mode; @@ -1112,7 +1005,7 @@ int sk_reuseport_attach_filter(struct sock_fprog * fprog,struct sock * sk) #include -int smp_call_function_single(int cpu,void (* func)(void * info),void * info,int wait) +int smp_call_function_single(int cpu,smp_call_func_t func,void * info,int wait) { lx_emul_trace_and_stop(__func__); } diff --git a/repos/pc/src/lib/wifi/lx_emul.c b/repos/pc/src/lib/wifi/lx_emul.c index e5340ddf20..2f307ae823 100644 --- a/repos/pc/src/lib/wifi/lx_emul.c +++ b/repos/pc/src/lib/wifi/lx_emul.c @@ -574,3 +574,33 @@ void kvfree_call_rcu(struct rcu_head * head,rcu_callback_t func) void *ptr = (void *) head - (unsigned long) func; kvfree(ptr); } + + +#include +#include + +int pci_write_config_byte(const struct pci_dev * dev,int where,u8 val) +{ + enum { PCI_CFG_RETRY_TIMEOUT = 0x41 }; + + switch (where) { + /* + * iwlwifi: "We disable the RETRY_TIMEOUT register (0x41) to keep + * PCI Tx retries from interfering with C3 CPU state" + */ + case PCI_CFG_RETRY_TIMEOUT: + return 0; + }; + lx_emul_trace_and_stop(__func__); +} + + +int pci_read_config_word(const struct pci_dev * dev,int where,u16 * val) +{ + switch (where) { + case PCI_COMMAND: + *val = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO; + return 0; + }; + lx_emul_trace_and_stop(__func__); +} diff --git a/repos/pc/src/lib/wifi/spec/x86_32/source.list b/repos/pc/src/lib/wifi/spec/x86_32/source.list index 94cbcb048b..35f22c35b1 100644 --- a/repos/pc/src/lib/wifi/spec/x86_32/source.list +++ b/repos/pc/src/lib/wifi/spec/x86_32/source.list @@ -1,5 +1,4 @@ arch/x86/lib/hweight.S -arch/x86/pci/legacy.c certs/common.c crypto/acompress.c crypto/aead.c @@ -117,18 +116,7 @@ drivers/net/wireless/intel/iwlwifi/pcie/trans.c drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c drivers/net/wireless/intel/iwlwifi/pcie/tx.c drivers/net/wireless/intel/iwlwifi/queue/tx.c -drivers/pci/access.c -drivers/pci/bus.c -drivers/pci/host-bridge.c -drivers/pci/msi.c drivers/pci/pci-driver.c -drivers/pci/pci-sysfs.c -drivers/pci/pci.c -drivers/pci/probe.c -drivers/pci/rom.c -drivers/pci/search.c -drivers/pci/setup-res.c -drivers/pci/slot.c fs/nls/nls_base.c kernel/irq/chip.c kernel/irq/devres.c @@ -187,7 +175,6 @@ lib/kstrtox.c lib/list_sort.c lib/math/div64.c lib/nlattr.c -lib/pci_iomap.c lib/radix-tree.c lib/rbtree.c lib/refcount.c diff --git a/repos/pc/src/lib/wifi/spec/x86_64/source.list b/repos/pc/src/lib/wifi/spec/x86_64/source.list index f6e3ae909b..40f2646615 100644 --- a/repos/pc/src/lib/wifi/spec/x86_64/source.list +++ b/repos/pc/src/lib/wifi/spec/x86_64/source.list @@ -1,5 +1,4 @@ arch/x86/lib/hweight.S -arch/x86/pci/legacy.c certs/common.c crypto/acompress.c crypto/aead.c @@ -117,18 +116,7 @@ drivers/net/wireless/intel/iwlwifi/pcie/trans.c drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c drivers/net/wireless/intel/iwlwifi/pcie/tx.c drivers/net/wireless/intel/iwlwifi/queue/tx.c -drivers/pci/access.c -drivers/pci/bus.c -drivers/pci/host-bridge.c -drivers/pci/msi.c drivers/pci/pci-driver.c -drivers/pci/pci-sysfs.c -drivers/pci/pci.c -drivers/pci/probe.c -drivers/pci/rom.c -drivers/pci/search.c -drivers/pci/setup-res.c -drivers/pci/slot.c fs/nls/nls_base.c kernel/irq/chip.c kernel/irq/devres.c @@ -186,7 +174,6 @@ lib/kobject.c lib/kstrtox.c lib/list_sort.c lib/nlattr.c -lib/pci_iomap.c lib/radix-tree.c lib/rbtree.c lib/refcount.c diff --git a/repos/pc/src/test/driver_time/dummies.c b/repos/pc/src/test/driver_time/dummies.c index 188ff680d6..efb54bd300 100644 --- a/repos/pc/src/test/driver_time/dummies.c +++ b/repos/pc/src/test/driver_time/dummies.c @@ -40,6 +40,15 @@ int ___ratelimit(struct ratelimit_state * rs, const char * func) return 1; } + +#include + +long io_schedule_timeout(long timeout) +{ + lx_emul_trace_and_stop(__func__); +} + + void register_syscore_ops(struct syscore_ops * ops) { lx_emul_trace(__func__); diff --git a/repos/pc/src/test/driver_time/generated_dummies.c b/repos/pc/src/test/driver_time/generated_dummies.c index a9436b07b2..04b188f12e 100644 --- a/repos/pc/src/test/driver_time/generated_dummies.c +++ b/repos/pc/src/test/driver_time/generated_dummies.c @@ -1,7 +1,7 @@ /* * \brief Dummy definitions of Linux Kernel functions * \author Automatically generated file - do no edit - * \date 2022-05-06 + * \date 2022-09-27 */ #include @@ -23,6 +23,14 @@ const char * __clk_get_name(const struct clk * clk) } +#include + +void __put_task_struct(struct task_struct * tsk) +{ + lx_emul_trace_and_stop(__func__); +} + + #include void __srcu_read_unlock(struct srcu_struct * ssp,int idx) @@ -31,49 +39,9 @@ void __srcu_read_unlock(struct srcu_struct * ssp,int idx) } -#include +#include -int printk_deferred(const char * fmt,...) -{ - lx_emul_trace_and_stop(__func__); -} - - -#include - -void irq_work_tick(void) -{ - lx_emul_trace_and_stop(__func__); -} - - -#include - -asmlinkage __visible void dump_stack(void) -{ - lx_emul_trace_and_stop(__func__); -} - - -#include - -int io_schedule_prepare(void) -{ - lx_emul_trace_and_stop(__func__); -} - - -#include - -void io_schedule_finish(int token) -{ - lx_emul_trace_and_stop(__func__); -} - - -#include - -long io_schedule_timeout(long timeout) +unsigned long _copy_to_user(void __user * to,const void * from,unsigned long n) { lx_emul_trace_and_stop(__func__); } @@ -88,15 +56,47 @@ void ack_bad_irq(unsigned int irq) #include -int kobject_synth_uevent(struct kobject * kobj,const char * buf,size_t count) +int add_uevent_var(struct kobj_uevent_env * env,const char * format,...) { lx_emul_trace_and_stop(__func__); } -#include +#include -int add_uevent_var(struct kobj_uevent_env * env,const char * format,...) +asmlinkage __visible void dump_stack(void) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +bool file_ns_capable(const struct file * file,struct user_namespace * ns,int cap) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void fwnode_remove_software_node(struct fwnode_handle * fwnode) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int get_option(char ** str,int * pint) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +struct pseudo_fs_context * init_pseudo(struct fs_context * fc,unsigned long magic) { lx_emul_trace_and_stop(__func__); } @@ -107,9 +107,36 @@ int add_uevent_var(struct kobj_uevent_env * env,const char * format,...) bool initcall_debug; -#include +#include -struct irq_chip no_irq_chip; +void io_schedule_finish(int token) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int io_schedule_prepare(void) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void irq_work_tick(void) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +bool is_software_node(const struct fwnode_handle * fwnode) +{ + lx_emul_trace_and_stop(__func__); +} #include @@ -125,49 +152,30 @@ void kill_anon_super(struct super_block * sb) } -#include +#include -bool is_software_node(const struct fwnode_handle * fwnode) +int kobject_synth_uevent(struct kobject * kobj,const char * buf,size_t count) { lx_emul_trace_and_stop(__func__); } -#include +#include -void fwnode_remove_software_node(struct fwnode_handle * fwnode) +struct irq_chip no_irq_chip; + + +#include + +void note_interrupt(struct irq_desc * desc,irqreturn_t action_ret) { lx_emul_trace_and_stop(__func__); } -#include +#include -void __put_task_struct(struct task_struct * tsk) -{ - lx_emul_trace_and_stop(__func__); -} - - -#include - -int get_option(char ** str,int * pint) -{ - lx_emul_trace_and_stop(__func__); -} - - -#include - -void wake_q_add_safe(struct wake_q_head * head,struct task_struct * task) -{ - lx_emul_trace_and_stop(__func__); -} - - -#include - -bool file_ns_capable(const struct file * file,struct user_namespace * ns,int cap) +int printk_deferred(const char * fmt,...) { lx_emul_trace_and_stop(__func__); } @@ -181,25 +189,9 @@ void seq_printf(struct seq_file * m,const char * f,...) } -#include - -struct pseudo_fs_context * init_pseudo(struct fs_context * fc,unsigned long magic) -{ - lx_emul_trace_and_stop(__func__); -} - - #include -int smp_call_function_single(int cpu,void (* func)(void * info),void * info,int wait) -{ - lx_emul_trace_and_stop(__func__); -} - - -#include - -unsigned long _copy_to_user(void __user * to,const void * from,unsigned long n) +int smp_call_function_single(int cpu,smp_call_func_t func,void * info,int wait) { lx_emul_trace_and_stop(__func__); } @@ -216,3 +208,12 @@ int string_escape_mem(const char * src,size_t isz,char * dst,size_t osz,unsigned { lx_emul_trace_and_stop(__func__); } + + +#include + +void wake_q_add_safe(struct wake_q_head * head,struct task_struct * task) +{ + lx_emul_trace_and_stop(__func__); +} + diff --git a/repos/pc/src/test/driver_time/source.list b/repos/pc/src/test/driver_time/source.list index 0bcffb7da8..ef8f09d03b 100644 --- a/repos/pc/src/test/driver_time/source.list +++ b/repos/pc/src/test/driver_time/source.list @@ -7,6 +7,7 @@ drivers/base/devres.c drivers/base/driver.c drivers/base/platform.c drivers/base/property.c +drivers/pci/pci-driver.c kernel/async.c kernel/irq/chip.c kernel/irq/devres.c