From 6c65e436bff524709ac1ed6ea3947a15cde33b98 Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Mon, 13 Apr 2015 14:29:00 +0200 Subject: [PATCH] usb: use io_mem on x86 via platform driver Issue #1487 --- repos/dde_linux/run/usb_hid.run | 1 + .../src/lib/usb/arm/platform_device.c | 39 +++++++++++ repos/dde_linux/src/lib/usb/include/lx_emul.h | 6 -- repos/dde_linux/src/lib/usb/lx_emul.cc | 43 ------------ repos/dde_linux/src/lib/usb/pci_driver.cc | 65 ++++++++++++++++++- 5 files changed, 103 insertions(+), 51 deletions(-) diff --git a/repos/dde_linux/run/usb_hid.run b/repos/dde_linux/run/usb_hid.run index b7063f512..70d45eebd 100644 --- a/repos/dde_linux/run/usb_hid.run +++ b/repos/dde_linux/run/usb_hid.run @@ -120,6 +120,7 @@ lappend_if [have_spec gpio] boot_modules gpio_drv build_boot_image $boot_modules append qemu_args " -m 256 -usb -usbdevice mouse -usbdevice keyboard" +append qemu_args " -device usb-ehci,id=ehci" run_genode_until forever diff --git a/repos/dde_linux/src/lib/usb/arm/platform_device.c b/repos/dde_linux/src/lib/usb/arm/platform_device.c index 14cace167..d974df3f8 100644 --- a/repos/dde_linux/src/lib/usb/arm/platform_device.c +++ b/repos/dde_linux/src/lib/usb/arm/platform_device.c @@ -186,3 +186,42 @@ void platform_set_drvdata(struct platform_device *pdev, void *data) } +/********************** + ** asm-generic/io.h ** + **********************/ + +void *_ioremap(resource_size_t phys_addr, unsigned long size, int wc) +{ + dde_kit_addr_t map_addr; + if (dde_kit_request_mem(phys_addr, size, wc, &map_addr)) { + panic("Failed to request I/O memory: [%zx,%lx)", phys_addr, phys_addr + size); + return 0; + } + return (void *)map_addr; +} + + +void *ioremap(resource_size_t offset, unsigned long size) +{ + return _ioremap(offset, size, 0); +} + + +void *devm_ioremap(struct device *dev, resource_size_t offset, + unsigned long size) +{ + return _ioremap(offset, size, 0); +} + + +void *devm_ioremap_nocache(struct device *dev, resource_size_t offset, + unsigned long size) +{ + return _ioremap(offset, size, 0); +} + + +void *devm_ioremap_resource(struct device *dev, struct resource *res) +{ + return _ioremap(res->start, res->end - res->start, 0); +} diff --git a/repos/dde_linux/src/lib/usb/include/lx_emul.h b/repos/dde_linux/src/lib/usb/include/lx_emul.h index 9ff20f11f..cd37530c8 100644 --- a/repos/dde_linux/src/lib/usb/include/lx_emul.h +++ b/repos/dde_linux/src/lib/usb/include/lx_emul.h @@ -2222,12 +2222,6 @@ void *devm_ioremap(struct device *dev, resource_size_t offset, void *devm_ioremap_nocache(struct device *dev, resource_size_t offset, unsigned long size); - -/** - * Map I/O memory write combined - */ -void *ioremap_wc(resource_size_t phys_addr, unsigned long size); - #define ioremap_nocache ioremap void *phys_to_virt(unsigned long address); diff --git a/repos/dde_linux/src/lib/usb/lx_emul.cc b/repos/dde_linux/src/lib/usb/lx_emul.cc index 0d4521552..ad52977b3 100644 --- a/repos/dde_linux/src/lib/usb/lx_emul.cc +++ b/repos/dde_linux/src/lib/usb/lx_emul.cc @@ -682,49 +682,6 @@ void kmem_cache_free(struct kmem_cache *cache, void *objp) ** asm-generic/io.h ** **********************/ -void *_ioremap(resource_size_t phys_addr, unsigned long size, int wc) -{ - dde_kit_addr_t map_addr; - if (dde_kit_request_mem(phys_addr, size, wc, &map_addr)) { - PERR("Failed to request I/O memory: [%zx,%lx)", phys_addr, phys_addr + size); - return 0; - } - return (void *)map_addr; -} - - -void *ioremap_wc(resource_size_t phys_addr, unsigned long size) -{ - return _ioremap(phys_addr, size, 1); -} - - -void *ioremap(resource_size_t offset, unsigned long size) -{ - return _ioremap(offset, size, 0); -} - - -void *devm_ioremap(struct device *dev, resource_size_t offset, - unsigned long size) -{ - return ioremap(offset, size); -} - - -void *devm_ioremap_nocache(struct device *dev, resource_size_t offset, - unsigned long size) -{ - return ioremap(offset, size); -} - - -void *devm_ioremap_resource(struct device *dev, struct resource *res) -{ - return _ioremap(res->start, res->end - res->start, 0); -} - - void *phys_to_virt(unsigned long address) { return (void *)Malloc::dma()->virt_addr(address); diff --git a/repos/dde_linux/src/lib/usb/pci_driver.cc b/repos/dde_linux/src/lib/usb/pci_driver.cc index fb8297490..39242894b 100644 --- a/repos/dde_linux/src/lib/usb/pci_driver.cc +++ b/repos/dde_linux/src/lib/usb/pci_driver.cc @@ -12,12 +12,12 @@ */ /* Genode base includes */ -#include #include +#include #include +#include /* Genode os includes */ -#include #include #include @@ -207,6 +207,29 @@ class Pci_driver : public Genode::List::Element return Genode::Irq_session_capability(); } + + static Genode::Io_mem_session_capability io_mem(resource_size_t phys) { + + for (Pci_driver *d = _drivers().first(); d; d = d->next()) { + if (!d->_dev) + continue; + + uint8_t bar = 0; + for (unsigned bar = 0; bar < PCI_ROM_RESOURCE; bar++) { + if ((pci_resource_flags(d->_dev, bar) & IORESOURCE_MEM) && + (pci_resource_start(d->_dev, bar) == phys)) + break; + } + if (bar >= PCI_ROM_RESOURCE) + continue; + + Pci::Device_client client(d->_cap); + return client.io_mem(bar); + } + + PERR("Device using i/o memory of address %zx is unknown", phys); + return Genode::Io_mem_session_capability(); + } }; /******************************** @@ -443,3 +466,41 @@ Genode::Irq_session_capability platform_irq_activate(int irq) { return Pci_driver::irq_cap(irq); } + +/****************** + ** MMIO regions ** + ******************/ + +class Mem_range : public Genode::Io_mem_session_client +{ + private: + + Genode::Io_mem_dataspace_capability _ds; + Genode::addr_t _vaddr; + + public: + + Mem_range(Genode::addr_t base, + Genode::Io_mem_session_capability io_cap) + : + Io_mem_session_client(io_cap), _ds(dataspace()), _vaddr(0UL) + { + _vaddr = Genode::env()->rm_session()->attach(_ds); + _vaddr |= base & 0xfffUL; + } + + Genode::addr_t vaddr() const { return _vaddr; } +}; + + +void *ioremap(resource_size_t phys_addr, unsigned long size) +{ + Mem_range * io_mem = new (Genode::env()->heap()) Mem_range(phys_addr, Pci_driver::io_mem(phys_addr)); + if (io_mem->vaddr()) + return (void *)io_mem->vaddr(); + + PERR("Failed to request I/O memory: [%zx,%lx)", phys_addr, + phys_addr + size); + + return nullptr; +}