dde_kit: use io ports via device interface

Issue #1487
This commit is contained in:
Alexander Boettcher 2015-04-29 13:59:54 +02:00 committed by Christian Helmuth
parent c84817dd7b
commit b7ca04ddde
8 changed files with 69 additions and 70 deletions

View File

@ -91,7 +91,8 @@ class Pci_driver : public Genode::List<Pci_driver>::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;

View File

@ -11,6 +11,7 @@
* under the terms of the GNU General Public License version 2.
*/
#include <timer_session/connection.h>
#include <pci_device/client.h>
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;
}

View File

@ -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)

View File

@ -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 <io_port_session/capability.h>
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);
};

View File

@ -23,6 +23,8 @@
#include <base/printf.h>
#include <dataspace/client.h>
#include <io_port_session/capability.h>
extern "C" {
#include <dde_kit/pci.h>
#include <dde_kit/pgtab.h>
@ -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 **
********************************/

View File

@ -23,6 +23,8 @@
#include <pci_session/connection.h>
#include <pci_device/client.h>
#include <io_port_session/capability.h>
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);
}
};
}

View File

@ -25,6 +25,8 @@ extern "C" {
#include <dde_kit/pgtab.h>
}
#include "device.h"
using namespace Genode;
static const bool verbose = false;
@ -152,22 +154,25 @@ static Range_database<Port_range> *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 (...) {

View File

@ -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 */