mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-18 18:56:29 +00:00
parent
c84817dd7b
commit
b7ca04ddde
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
27
repos/os/src/lib/dde_kit/device.h
Normal file
27
repos/os/src/lib/dde_kit/device.h
Normal 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);
|
||||
};
|
@ -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 **
|
||||
********************************/
|
||||
|
@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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 (...) {
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user