pci: convert to platform_drv

Fixes #1542
This commit is contained in:
Alexander Boettcher
2015-06-08 09:05:32 +02:00
committed by Christian Helmuth
parent 32e792dc74
commit 1f40d9de6a
84 changed files with 721 additions and 1324 deletions

View File

@ -16,9 +16,9 @@
#include <irq_session/capability.h>
#include <io_mem_session/capability.h>
namespace Platform { class Device; }
namespace Platform { class Abstract_device; }
struct Platform::Device
struct Platform::Abstract_device
{
/**
* Get IRQ session capability

View File

@ -0,0 +1,19 @@
/*
* \brief PCI device capability type
* \author Norman Feske
* \date 2008-08-16
*/
/*
* Copyright (C) 2008-2013 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 <base/capability.h>
#include <platform_device/platform_device.h>
namespace Platform { typedef Genode::Capability<Device> Device_capability; }

View File

@ -0,0 +1,58 @@
/*
* \brief Client-side interface for PCI device
* \author Norman Feske
* \date 2008-01-28
*/
/*
* Copyright (C) 2008-2013 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 <platform_session/platform_session.h>
#include <platform_device/platform_device.h>
#include <base/rpc_client.h>
#include <io_mem_session/io_mem_session.h>
namespace Platform { struct Device_client; }
struct Platform::Device_client : public Genode::Rpc_client<Device>
{
Device_client(Device_capability device)
: Genode::Rpc_client<Device>(device) { }
void bus_address(unsigned char *bus, unsigned char *dev, unsigned char *fn) override {
call<Rpc_bus_address>(bus, dev, fn); }
unsigned short vendor_id() override {
return call<Rpc_vendor_id>(); }
unsigned short device_id() override {
return call<Rpc_device_id>(); }
unsigned class_code() override {
return call<Rpc_class_code>(); }
Resource resource(int resource_id) override {
return call<Rpc_resource>(resource_id); }
unsigned config_read(unsigned char address, Access_size size) override {
return call<Rpc_config_read>(address, size); }
void config_write(unsigned char address, unsigned value, Access_size size) override {
call<Rpc_config_write>(address, value, size); }
Genode::Irq_session_capability irq(Genode::uint8_t id) override {
return call<Rpc_irq>(id); }
Genode::Io_port_session_capability io_port(Genode::uint8_t id) override {
return call<Rpc_io_port>(id); }
Genode::Io_mem_session_capability io_mem(Genode::uint8_t id) override {
return call<Rpc_io_mem>(id); }
};

View File

@ -0,0 +1,259 @@
/*
* \brief PCI-device interface
* \author Norman Feske
* \date 2008-01-28
*/
/*
* Copyright (C) 2008-2013 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 <base/rpc.h>
#include <base/signal.h>
#include <base/exception.h>
#include <io_mem_session/io_mem_session.h>
#include <io_port_session/capability.h>
#include <irq_session/capability.h>
#include <ram_session/ram_session.h>
/* os includes */
#include <platform/device.h>
namespace Platform { struct Device; }
struct Platform::Device : Platform::Abstract_device
{
/*********************
** Exception types **
*********************/
class Alloc_failed : public Genode::Exception { };
class Quota_exceeded : public Alloc_failed { };
class Resource
{
private:
unsigned _bar; /* content of base-address register */
unsigned _size; /* resource size */
public:
/**
* Resource type, either port I/O resource or memory-mapped resource
*/
enum Type { IO, MEMORY, INVALID };
/**
* Default constructor
*/
Resource() { }
/**
* Constructor
*
* \param bar content of base-address register
* \param size resource size
*
* This constructor is only used by the PCI bus driver
* that implements the server-side of the the PCI session.
* If bar is set to zero, the constructed resource description
* represents an INVALID resource.
*/
Resource(unsigned bar, unsigned size)
: _bar(bar), _size(size) { }
/**
* Return base address of resource
*/
unsigned base()
{
/*
* Mask out the resource-description bits of the base
* address register. I/O resources use the lowest 3
* bits, memory resources use the lowest 4 bits.
*/
return _bar & ((type() == IO) ? ~7 : ~15);
}
/**
* Return resource size in bytes
*/
unsigned size() { return _size; }
/**
* Return true if resource is prefetchable memory
*/
bool prefetchable()
{
return type() == MEMORY && (_bar & (1 << 3));
}
/**
* Return resource type
*/
Type type()
{
if (_bar == 0)
return INVALID;
return (_bar & 1) ? IO : MEMORY;
}
/**
* Return raw register content
*/
unsigned bar() const { return _bar; }
};
enum { NUM_RESOURCES = 6 };
virtual ~Device() { }
/**
* Return bus, device, and function number of the device
*/
virtual void bus_address(unsigned char *bus, unsigned char *dev,
unsigned char *fn) = 0;
/**
* Return vendor ID obtained from the PCI config space
*/
virtual unsigned short vendor_id() = 0;
/**
* Return device ID obtained from the PCI config space
*/
virtual unsigned short device_id() = 0;
/**
* Return device class code from the PCI config space
*/
virtual unsigned class_code() = 0;
/**
* Query PCI-resource information
*
* \param resource_id index of according PCI resource of the device
*
* \return resource description
* \retval INVALID the supplied resource ID is invalid
*/
virtual Resource resource(int resource_id) = 0;
/**
* Access size for operations directly accessing the config space
*/
enum Access_size { ACCESS_8BIT, ACCESS_16BIT, ACCESS_32BIT };
/**
* Read configuration space
*/
virtual unsigned config_read(unsigned char address, Access_size size) = 0;
/**
* Write configuration space
*/
virtual void config_write(unsigned char address, unsigned value,
Access_size size) = 0;
/**
* Query Io_port of specified bar
*
* \param id index of according PCI resource of the device
*/
virtual Genode::Io_port_session_capability io_port(Genode::uint8_t id) = 0;
/*
* The base classes are defined as follows:
*
* 0x00 | legacy device
* 0x01 | mass-storage controller
* 0x02 | network controller
* 0x03 | display controller
* 0x04 | multimedia device
* 0x05 | memory controller
* 0x06 | bridge device
* 0x07 | simple-communication controller
* 0x08 | base-system peripheral
* 0x09 | input device
* 0x0a | docking station
* 0x0b | processor
* 0x0c | serial bus controller
* 0x0d | wireless controller
* 0x0e | intelligent I/O controller
* 0x0f | satellite-communications controller
* 0x10 | encryption/decryption controller
* 0x11 | data-acquisition and signal-processing controller
* 0x12 | reserved
* ... |
* 0xff | device does not fit in any of the defined classes
*/
unsigned base_class() { return class_code() >> 16; }
unsigned sub_class() { return (class_code() >> 8) & 0xff; }
/**
* Convenience method to translate a PCI physical BAR id to a Genode
* virtual one usable with the io_port and io_mem methods. The virtual id
* is solely valid for the specific BAR type.
*/
Genode::uint8_t phys_bar_to_virt(Genode::uint8_t phys_bar)
{
Genode::uint8_t virt_io_port = 0, virt_io_mem = 0;
for (unsigned i = 0; i < phys_bar; i++) {
Resource::Type type = resource(i).type();
if (type == Resource::Type::IO)
virt_io_port ++;
else if (type == Resource::Type::MEMORY)
virt_io_mem ++;
}
Resource::Type type = resource(phys_bar).type();
return type == Resource::Type::IO ? virt_io_port : virt_io_mem;
}
/*********************
** RPC declaration **
*********************/
GENODE_RPC(Rpc_bus_address, void, bus_address,
unsigned char *, unsigned char *, unsigned char *);
GENODE_RPC(Rpc_vendor_id, unsigned short, vendor_id);
GENODE_RPC(Rpc_device_id, unsigned short, device_id);
GENODE_RPC(Rpc_class_code, unsigned, class_code);
GENODE_RPC(Rpc_resource, Resource, resource, int);
GENODE_RPC(Rpc_config_read, unsigned, config_read,
unsigned char, Access_size);
GENODE_RPC(Rpc_config_write, void, config_write,
unsigned char, unsigned, Access_size);
GENODE_RPC(Rpc_irq, Genode::Irq_session_capability, irq, Genode::uint8_t);
GENODE_RPC_THROW(Rpc_io_port, Genode::Io_port_session_capability, io_port,
GENODE_TYPE_LIST(Quota_exceeded),
Genode::uint8_t);
GENODE_RPC_THROW(Rpc_io_mem, Genode::Io_mem_session_capability, io_mem,
GENODE_TYPE_LIST(Quota_exceeded),
Genode::uint8_t);
typedef Genode::Meta::Type_tuple<Rpc_bus_address,
Genode::Meta::Type_tuple<Rpc_vendor_id,
Genode::Meta::Type_tuple<Rpc_device_id,
Genode::Meta::Type_tuple<Rpc_class_code,
Genode::Meta::Type_tuple<Rpc_resource,
Genode::Meta::Type_tuple<Rpc_config_read,
Genode::Meta::Type_tuple<Rpc_config_write,
Genode::Meta::Type_tuple<Rpc_irq,
Genode::Meta::Type_tuple<Rpc_io_port,
Genode::Meta::Type_tuple<Rpc_io_mem,
Genode::Meta::Empty>
> > > > > > > > > Rpc_functions;
};

View File

@ -0,0 +1,52 @@
/*
* \brief Client-side PCI-session interface
* \author Norman Feske
* \date 2008-01-28
*/
/*
* Copyright (C) 2008-2013 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 <base/rpc_client.h>
#include <platform_device/client.h>
#include <platform_session/capability.h>
namespace Platform { struct Client; }
struct Platform::Client : public Genode::Rpc_client<Session>
{
Client(Session_capability session)
: Genode::Rpc_client<Session>(session) { }
Device_capability first_device(unsigned device_class = 0,
unsigned class_mask = 0) override {
return call<Rpc_first_device>(device_class, class_mask); }
Device_capability next_device(Device_capability prev_device,
unsigned device_class = 0,
unsigned class_mask = 0) override {
return call<Rpc_next_device>(prev_device, device_class, class_mask); }
void release_device(Device_capability device) override {
call<Rpc_release_device>(device); }
Genode::Io_mem_dataspace_capability config_extended(Device_capability device_cap) override {
return call<Rpc_config_extended>(device_cap); }
Genode::Ram_dataspace_capability alloc_dma_buffer(Genode::size_t size) override {
return call<Rpc_alloc_dma_buffer>(size); }
void free_dma_buffer(Genode::Ram_dataspace_capability cap) override {
call<Rpc_free_dma_buffer>(cap); }
Device_capability device(String const &device) override {
return call<Rpc_device>(device); }
};

View File

@ -0,0 +1,29 @@
/*
* \brief Connection to Platform service
* \author Norman Feske
* \date 2008-08-22
*/
/*
* Copyright (C) 2008-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 <base/connection.h>
#include <platform_session/client.h>
namespace Platform { struct Connection; }
struct Platform::Connection : Genode::Connection<Session>, Client
{
Connection()
:
Genode::Connection<Session>(session("ram_quota=12K")),
Client(cap())
{ }
};

View File

@ -0,0 +1,109 @@
/*
* \brief Platform session interface
* \author Norman Feske
* \date 2008-01-28
*/
/*
* Copyright (C) 2008-2013 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
/* base */
#include <session/session.h>
#include <ram_session/ram_session.h>
/* os */
#include <platform_device/platform_device.h>
#include <platform_device/capability.h>
namespace Platform { struct Session; }
struct Platform::Session : Genode::Session
{
static const char *service_name() { return "Platform"; }
virtual ~Session() { }
/**
* Find first accessible device
*/
virtual Device_capability first_device(unsigned, unsigned) = 0;
/**
* Find next accessible device
*
* \param prev_device previous device
*
* The 'prev_device' argument is used to iterate through all
* devices.
*/
virtual Device_capability next_device(Device_capability prev_device,
unsigned, unsigned) = 0;
/**
* Free server-internal data structures representing the device
*
* Use this method to relax the heap partition of your PCI session.
*/
virtual void release_device(Device_capability device) = 0;
/**
* Provide mapping to device configuration space of 4k, known as
* "Enhanced Configuration Access Mechanism (ECAM) for PCI Express
*/
virtual Genode::Io_mem_dataspace_capability config_extended(Device_capability) = 0;
typedef Genode::Rpc_in_buffer<8> String;
/**
* Provide non-PCI device known by unique name.
*/
virtual Device_capability device(String const &string) = 0;
/**
* Allocate memory suitable for DMA.
*/
virtual Genode::Ram_dataspace_capability alloc_dma_buffer(Genode::size_t) = 0;
/**
* Free previously allocated DMA memory
*/
virtual void free_dma_buffer(Genode::Ram_dataspace_capability) = 0;
/*********************
** RPC declaration **
*********************/
GENODE_RPC_THROW(Rpc_first_device, Device_capability, first_device,
GENODE_TYPE_LIST(Platform::Device::Quota_exceeded),
unsigned, unsigned);
GENODE_RPC_THROW(Rpc_next_device, Device_capability, next_device,
GENODE_TYPE_LIST(Platform::Device::Quota_exceeded),
Device_capability, unsigned, unsigned);
GENODE_RPC(Rpc_release_device, void, release_device, Device_capability);
GENODE_RPC_THROW(Rpc_config_extended, Genode::Io_mem_dataspace_capability,
config_extended,
GENODE_TYPE_LIST(Platform::Device::Quota_exceeded),
Device_capability);
GENODE_RPC_THROW(Rpc_alloc_dma_buffer, Genode::Ram_dataspace_capability,
alloc_dma_buffer,
GENODE_TYPE_LIST(Platform::Device::Quota_exceeded),
Genode::size_t);
GENODE_RPC(Rpc_free_dma_buffer, void, free_dma_buffer,
Genode::Ram_dataspace_capability);
GENODE_RPC_THROW(Rpc_device, Device_capability, device,
GENODE_TYPE_LIST(Platform::Device::Quota_exceeded),
String const &);
GENODE_RPC_INTERFACE(Rpc_first_device, Rpc_next_device,
Rpc_release_device, Rpc_config_extended,
Rpc_alloc_dma_buffer, Rpc_free_dma_buffer,
Rpc_device);
};