parent
c84817dd7b
commit
b7ca04ddde
|
@ -91,7 +91,8 @@ class Pci_driver : public Genode::List<Pci_driver>::Element
|
||||||
|
|
||||||
/* request port I/O session */
|
/* request port I/O session */
|
||||||
if (res.type() == Device::Resource::IO) {
|
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)",
|
PERR("Failed to request I/O: [%u,%u)",
|
||||||
res.base(), res.base() + res.size());
|
res.base(), res.base() + res.size());
|
||||||
io = true;
|
io = true;
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
*/
|
*/
|
||||||
#include <timer_session/connection.h>
|
#include <timer_session/connection.h>
|
||||||
|
#include <pci_device/client.h>
|
||||||
|
|
||||||
extern "C"
|
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)
|
extern "C" oss_native_word pci_map_io(struct _oss_device_t *osdev, int resource, unsigned base)
|
||||||
{
|
{
|
||||||
if (osdev->res[resource].io)
|
if (resource >= Pci::Device::NUM_RESOURCES || resource < 0 ||
|
||||||
dde_kit_request_io(osdev->res[resource].base, osdev->res[resource].size);
|
!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;
|
return base;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,9 @@
|
||||||
*
|
*
|
||||||
* \return 0 on success, -1 otherwise
|
* \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)
|
* Free I/O port range (x86)
|
||||||
|
|
|
@ -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);
|
||||||
|
};
|
|
@ -23,6 +23,8 @@
|
||||||
#include <base/printf.h>
|
#include <base/printf.h>
|
||||||
#include <dataspace/client.h>
|
#include <dataspace/client.h>
|
||||||
|
|
||||||
|
#include <io_port_session/capability.h>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <dde_kit/pci.h>
|
#include <dde_kit/pci.h>
|
||||||
#include <dde_kit/pgtab.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 **
|
** Configuration space access **
|
||||||
********************************/
|
********************************/
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
#include <pci_session/connection.h>
|
#include <pci_session/connection.h>
|
||||||
#include <pci_device/client.h>
|
#include <pci_device/client.h>
|
||||||
|
|
||||||
|
#include <io_port_session/capability.h>
|
||||||
|
|
||||||
namespace Dde_kit {
|
namespace Dde_kit {
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
@ -152,6 +154,9 @@ namespace Dde_kit {
|
||||||
|
|
||||||
return Ram_dataspace_capability();
|
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
|
class Pci_tree
|
||||||
|
@ -285,6 +290,15 @@ namespace Dde_kit {
|
||||||
|
|
||||||
return _lookup(bdf)->alloc_dma_buffer(_pci_drv, size);
|
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);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,8 @@ extern "C" {
|
||||||
#include <dde_kit/pgtab.h>
|
#include <dde_kit/pgtab.h>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "device.h"
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
static const bool verbose = false;
|
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:
|
public:
|
||||||
|
|
||||||
Port_range(addr_t base, size_t size)
|
Port_range(addr_t base, size_t size, Io_port_session_capability cap)
|
||||||
: Range(base, size), Io_port_connection(base, size) {
|
: Range(base, size), Io_port_session_client(cap) {
|
||||||
ports()->insert(this); }
|
ports()->insert(this); }
|
||||||
|
|
||||||
~Port_range() { ports()->remove(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 {
|
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;
|
return 0;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
|
|
@ -512,67 +512,6 @@ static void test_resources()
|
||||||
PDBG("=== starting resource test ===");
|
PDBG("=== starting resource test ===");
|
||||||
|
|
||||||
dde_kit_addr_t addr, a; dde_kit_size_t size, s; int wc;
|
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;
|
dde_kit_addr_t vaddr; int ret;
|
||||||
|
|
||||||
/* should succeed */
|
/* should succeed */
|
||||||
|
|
Loading…
Reference in New Issue