From b7ca04ddde5c6c7580f7531be6193d1b747772ac Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Wed, 29 Apr 2015 13:59:54 +0200 Subject: [PATCH] dde_kit: use io ports via device interface Issue #1487 --- repos/dde_linux/src/lib/usb/pci_driver.cc | 3 +- repos/dde_oss/src/drivers/audio_out/os.cc | 9 +++- repos/os/include/dde_kit/resources.h | 4 +- repos/os/src/lib/dde_kit/device.h | 27 ++++++++++ repos/os/src/lib/dde_kit/pci.cc | 6 +++ repos/os/src/lib/dde_kit/pci_tree.h | 14 ++++++ repos/os/src/lib/dde_kit/resources.cc | 15 ++++-- repos/os/src/test/dde_kit/test.cc | 61 ----------------------- 8 files changed, 69 insertions(+), 70 deletions(-) create mode 100644 repos/os/src/lib/dde_kit/device.h diff --git a/repos/dde_linux/src/lib/usb/pci_driver.cc b/repos/dde_linux/src/lib/usb/pci_driver.cc index f17d9cf22..fb8297490 100644 --- a/repos/dde_linux/src/lib/usb/pci_driver.cc +++ b/repos/dde_linux/src/lib/usb/pci_driver.cc @@ -91,7 +91,8 @@ class Pci_driver : public Genode::List::Element /* request port I/O session */ if (res.type() == Device::Resource::IO) { - if (dde_kit_request_io(res.base(), res.size())) + if (dde_kit_request_io(res.base(), res.size(), i, bus, dev, + func)) PERR("Failed to request I/O: [%u,%u)", res.base(), res.base() + res.size()); io = true; diff --git a/repos/dde_oss/src/drivers/audio_out/os.cc b/repos/dde_oss/src/drivers/audio_out/os.cc index 93e182d9f..d8e59cf70 100644 --- a/repos/dde_oss/src/drivers/audio_out/os.cc +++ b/repos/dde_oss/src/drivers/audio_out/os.cc @@ -11,6 +11,7 @@ * under the terms of the GNU General Public License version 2. */ #include +#include extern "C" { @@ -115,8 +116,12 @@ extern "C" void *pci_map(oss_device_t *osdev, int resource, addr_t phys, size_t extern "C" oss_native_word pci_map_io(struct _oss_device_t *osdev, int resource, unsigned base) { - if (osdev->res[resource].io) - dde_kit_request_io(osdev->res[resource].base, osdev->res[resource].size); + if (resource >= Pci::Device::NUM_RESOURCES || resource < 0 || + !osdev->res[resource].io) + return 0; + + dde_kit_request_io(osdev->res[resource].base, osdev->res[resource].size, + resource, osdev->bus, osdev->dev, osdev->fun); return base; } diff --git a/repos/os/include/dde_kit/resources.h b/repos/os/include/dde_kit/resources.h index 49942d52b..a9e85324b 100644 --- a/repos/os/include/dde_kit/resources.h +++ b/repos/os/include/dde_kit/resources.h @@ -24,7 +24,9 @@ * * \return 0 on success, -1 otherwise */ -int dde_kit_request_io(dde_kit_addr_t start, dde_kit_size_t size); +int dde_kit_request_io(dde_kit_addr_t start, dde_kit_size_t size, + unsigned short bar, dde_kit_uint8_t bus, + dde_kit_uint8_t dev, dde_kit_uint8_t func); /** * Free I/O port range (x86) diff --git a/repos/os/src/lib/dde_kit/device.h b/repos/os/src/lib/dde_kit/device.h new file mode 100644 index 000000000..09b0eef26 --- /dev/null +++ b/repos/os/src/lib/dde_kit/device.h @@ -0,0 +1,27 @@ +/* + * \brief Lib internal interface to use and request resources provided by + * platform driver + * \author Alexander Boettcher + * \date 2015-04-05 + */ + +/* + * Copyright (C) 2015 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#pragma once + +#include + +namespace Dde_kit { class Device; } + +class Dde_kit::Device { + + public: + static Genode::Io_port_session_capability io_port(int bus, int dev, + int fun, + unsigned short bda); +}; diff --git a/repos/os/src/lib/dde_kit/pci.cc b/repos/os/src/lib/dde_kit/pci.cc index ea1f0b4d3..f53528158 100644 --- a/repos/os/src/lib/dde_kit/pci.cc +++ b/repos/os/src/lib/dde_kit/pci.cc @@ -23,6 +23,8 @@ #include #include +#include + extern "C" { #include #include @@ -43,6 +45,10 @@ static Dde_kit::Pci_tree *pci_tree(unsigned device_class = 0, } +Genode::Io_port_session_capability Dde_kit::Device::io_port(int bus, int dev, int fun, unsigned short bda) { + return pci_tree()->io_port(bus, dev, fun, bda); } + + /******************************** ** Configuration space access ** ********************************/ diff --git a/repos/os/src/lib/dde_kit/pci_tree.h b/repos/os/src/lib/dde_kit/pci_tree.h index 52ae6c154..00ddd2317 100644 --- a/repos/os/src/lib/dde_kit/pci_tree.h +++ b/repos/os/src/lib/dde_kit/pci_tree.h @@ -23,6 +23,8 @@ #include #include +#include + namespace Dde_kit { using namespace Genode; @@ -152,6 +154,9 @@ namespace Dde_kit { return Ram_dataspace_capability(); } + + Genode::Io_port_session_capability io_port(unsigned short bar) { + return _device.io_port(_device.phys_bar_to_virt(bar)); } }; class Pci_tree @@ -285,6 +290,15 @@ namespace Dde_kit { return _lookup(bdf)->alloc_dma_buffer(_pci_drv, size); } + + Io_port_session_capability io_port(int bus, int dev, int fun, unsigned short bda) + { + Lock::Guard lock_guard(_lock); + + unsigned short bdf = Pci_device::knit_bdf(bus, dev, fun); + + return _lookup(bdf)->io_port(bda); + } }; } diff --git a/repos/os/src/lib/dde_kit/resources.cc b/repos/os/src/lib/dde_kit/resources.cc index 2922f2718..2a0242e90 100644 --- a/repos/os/src/lib/dde_kit/resources.cc +++ b/repos/os/src/lib/dde_kit/resources.cc @@ -25,6 +25,8 @@ extern "C" { #include } +#include "device.h" + using namespace Genode; static const bool verbose = false; @@ -152,22 +154,25 @@ static Range_database *ports() } -class Port_range : public Range, public Io_port_connection +class Port_range : public Range, public Io_port_session_client { public: - Port_range(addr_t base, size_t size) - : Range(base, size), Io_port_connection(base, size) { + Port_range(addr_t base, size_t size, Io_port_session_capability cap) + : Range(base, size), Io_port_session_client(cap) { ports()->insert(this); } ~Port_range() { ports()->remove(this); } }; -extern "C" int dde_kit_request_io(dde_kit_addr_t addr, dde_kit_size_t size) +extern "C" int dde_kit_request_io(dde_kit_addr_t addr, dde_kit_size_t size, + unsigned short bar, dde_kit_uint8_t bus, + dde_kit_uint8_t dev, dde_kit_uint8_t func) { try { - new (env()->heap()) Port_range(addr, size); + + new (env()->heap()) Port_range(addr, size, Dde_kit::Device::io_port(bus, dev, func, bar)); return 0; } catch (...) { diff --git a/repos/os/src/test/dde_kit/test.cc b/repos/os/src/test/dde_kit/test.cc index ea7cf0d50..6f4506986 100644 --- a/repos/os/src/test/dde_kit/test.cc +++ b/repos/os/src/test/dde_kit/test.cc @@ -512,67 +512,6 @@ static void test_resources() PDBG("=== starting resource test ==="); dde_kit_addr_t addr, a; dde_kit_size_t size, s; int wc; - - /* should succeed */ - addr = 0xe000; size = 0x10; - PDBG("req [%04lx,%04lx) => %d", addr, addr + size, dde_kit_request_io(addr, size)); - PDBG("rel [%04lx,%04lx) => %d", addr, addr + size, dde_kit_release_io(addr, size)); - - /* should succeed */ - addr = 0x60; size = 0x1; - PDBG("req [%04lx,%04lx) => %d", addr, addr + size, dde_kit_request_io(addr, size)); - addr = 0x64; size = 0x1; - PDBG("req [%04lx,%04lx) => %d", addr, addr + size, dde_kit_request_io(addr, size)); - addr = 0x60; size = 0x1; - PDBG("rel [%04lx,%04lx) => %d", addr, addr + size, dde_kit_release_io(addr, size)); - addr = 0x64; size = 0x1; - PDBG("rel [%04lx,%04lx) => %d", addr, addr + size, dde_kit_release_io(addr, size)); - - /* use io_delay() port; should succeed */ - addr = 0x80; size = 0x1; - PDBG("req [%04lx,%04lx) => %d", addr, addr + size, dde_kit_request_io(addr, size)); - for (unsigned i = 0; i < 50; ++i) dde_kit_outb(0x80, 0xff); - PDBG("rel [%04lx,%04lx) => %d", addr, addr + size, dde_kit_release_io(addr, size)); - - /* PCI config; should fail if PCI driver loaded _and_ used */ - addr = 0xcf8; size = 0x8; - PDBG("req [%04lx,%04lx) => %d", addr, addr + size, dde_kit_request_io(addr, size)); - PDBG("rel [%04lx,%04lx) => %d", addr, addr + size, dde_kit_release_io(addr, size)); - - /* stress range database implementation */ - enum { MAX_ROUNDS = 15 }; - struct { - dde_kit_addr_t a; - dde_kit_size_t s; - bool req; - } round[MAX_ROUNDS] = { - { 0xe000, 16, true}, - { 0xe010, 16, true}, - { 0xe020, 16, true}, - { 0xe030, 16, true}, - { 0xdfe0, 16, true}, - { 0xdfd0, 16, true}, - { 0xe010, 16, false}, - { 0xe010, 16, false}, - { 0xe020, 8, false}, /* XXX currently remove whole allocated region */ - { 0xe028, 8, false}, /* XXX and, therefore, this fails */ - { 0xdfd0, 32, false}, /* XXX fails because regions are not merged */ - { 0xe030, 16, false}, - { 0xe000, 16, false}, - { 0xdfe0, 16, false}, - { 0xdfd0, 16, false}, - }; - - for (unsigned i = 0; i < MAX_ROUNDS; ++i) { - if (round[i].req) { - PDBG("mreq [%04lx,%04lx) => %d", - round[i].a, round[i].a + round[i].s, dde_kit_request_io(round[i].a, round[i].s)); - } else { - PDBG("mrel [%04lx,%04lx) => %d", - round[i].a, round[i].a + round[i].s, dde_kit_release_io(round[i].a, round[i].s)); - } - } - dde_kit_addr_t vaddr; int ret; /* should succeed */