mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 09:46:20 +00:00
parent
4e99925c7c
commit
1006571c85
@ -50,6 +50,9 @@ struct Pci::Device_client : public Genode::Rpc_client<Device>
|
||||
|
||||
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); }
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__PCI_DEVICE__CLIENT_H_ */
|
||||
|
@ -18,6 +18,7 @@
|
||||
#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>
|
||||
|
||||
@ -165,6 +166,12 @@ struct Pci::Device : Platform::Device
|
||||
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:
|
||||
@ -211,10 +218,21 @@ struct Pci::Device : Platform::Device
|
||||
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_INTERFACE(Rpc_bus_address, Rpc_vendor_id, Rpc_device_id,
|
||||
Rpc_class_code, Rpc_resource, Rpc_config_read,
|
||||
Rpc_config_write, Rpc_irq);
|
||||
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::Empty>
|
||||
> > > > > > > > Rpc_functions;
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__PCI_DEVICE__PCI_DEVICE_H_ */
|
||||
|
@ -23,16 +23,23 @@ class Nonpci::Ps2 : public Pci::Device_component
|
||||
enum {
|
||||
IRQ_KEYBOARD = 1,
|
||||
IRQ_MOUSE = 12,
|
||||
|
||||
ACCESS_WIDTH = 1,
|
||||
REG_DATA = 0x60,
|
||||
REG_STATUS = 0x64,
|
||||
};
|
||||
|
||||
Genode::Irq_connection _irq_mouse;
|
||||
Genode::Io_port_connection _data;
|
||||
Genode::Io_port_connection _status;
|
||||
|
||||
public:
|
||||
|
||||
Ps2(Genode::Rpc_entrypoint * ep, Pci::Session_component * session)
|
||||
:
|
||||
Pci::Device_component(ep, session, IRQ_KEYBOARD),
|
||||
_irq_mouse(IRQ_MOUSE)
|
||||
_irq_mouse(IRQ_MOUSE),
|
||||
_data(REG_DATA, ACCESS_WIDTH), _status(REG_STATUS, ACCESS_WIDTH)
|
||||
{ }
|
||||
|
||||
Genode::Irq_session_capability irq(Genode::uint8_t virt_irq) override
|
||||
@ -46,6 +53,16 @@ class Nonpci::Ps2 : public Pci::Device_component
|
||||
return Genode::Irq_session_capability();
|
||||
}
|
||||
}
|
||||
|
||||
Genode::Io_port_session_capability io_port(Genode::uint8_t io_port) override
|
||||
{
|
||||
if (io_port == 0)
|
||||
return _data.cap();
|
||||
if (io_port == 1)
|
||||
return _status.cap();
|
||||
|
||||
return Genode::Io_port_session_capability();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
38
repos/os/src/drivers/pci/pci_device.cc
Normal file
38
repos/os/src/drivers/pci/pci_device.cc
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* \brief PCI device component implementation
|
||||
* \author Alexander Boettcher
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "pci_session_component.h"
|
||||
#include "pci_device_component.h"
|
||||
|
||||
Genode::Io_port_session_capability Pci::Device_component::io_port(Genode::uint8_t v_id)
|
||||
{
|
||||
Genode::uint8_t max = sizeof(_io_port_conn) / sizeof(_io_port_conn[0]);
|
||||
Genode::uint8_t i = 0, r_id = 0;
|
||||
|
||||
for (Resource res = resource(0); i < max; i++, res = resource(i))
|
||||
{
|
||||
if (res.type() != Resource::IO)
|
||||
continue;
|
||||
|
||||
if (v_id != r_id) {
|
||||
r_id ++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_io_port_conn[v_id] == nullptr)
|
||||
_io_port_conn[v_id] = new (_slab_ioport) Genode::Io_port_connection(res.base(), res.size());
|
||||
|
||||
return _io_port_conn[v_id]->cap();
|
||||
}
|
||||
|
||||
return Genode::Io_port_session_capability();
|
||||
}
|
@ -40,6 +40,16 @@ class Pci::Device_component : public Genode::Rpc_object<Pci::Device>,
|
||||
Pci::Session_component *_session;
|
||||
Irq_session_component _irq_session;
|
||||
|
||||
enum {
|
||||
IO_BLOCK_SIZE = sizeof(Genode::Io_port_connection) *
|
||||
Device::NUM_RESOURCES + 32 + 8 * sizeof(void *)
|
||||
};
|
||||
Genode::Tslab<Genode::Io_port_connection, IO_BLOCK_SIZE> _slab_ioport;
|
||||
Genode::Slab_block _slab_ioport_block;
|
||||
char _slab_ioport_block_data[IO_BLOCK_SIZE];
|
||||
|
||||
Genode::Io_port_connection *_io_port_conn [Device::NUM_RESOURCES];
|
||||
|
||||
enum { PCI_IRQ = 0x3c };
|
||||
|
||||
public:
|
||||
@ -54,9 +64,16 @@ class Pci::Device_component : public Genode::Rpc_object<Pci::Device>,
|
||||
_device_config(device_config), _config_space(addr),
|
||||
_io_mem(0), _ep(ep), _session(session),
|
||||
_irq_session(_device_config.read(&_config_access, PCI_IRQ,
|
||||
Pci::Device::ACCESS_8BIT))
|
||||
Pci::Device::ACCESS_8BIT)),
|
||||
_slab_ioport(0, &_slab_ioport_block)
|
||||
{
|
||||
_ep->manage(&_irq_session);
|
||||
|
||||
for (unsigned i = 0; i < Device::NUM_RESOURCES; i++)
|
||||
_io_port_conn[i] = nullptr;
|
||||
|
||||
if (_slab_ioport.num_elem() != Device::NUM_RESOURCES)
|
||||
PERR("incorrect amount of space for io port resources");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -66,9 +83,13 @@ class Pci::Device_component : public Genode::Rpc_object<Pci::Device>,
|
||||
Pci::Session_component * session, unsigned irq)
|
||||
:
|
||||
_config_space(~0UL), _io_mem(0), _ep(ep), _session(session),
|
||||
_irq_session(irq)
|
||||
_irq_session(irq),
|
||||
_slab_ioport(0, &_slab_ioport_block)
|
||||
{
|
||||
_ep->manage(&_irq_session);
|
||||
|
||||
for (unsigned i = 0; i < Device::NUM_RESOURCES; i++)
|
||||
_io_port_conn[i] = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -77,6 +98,11 @@ class Pci::Device_component : public Genode::Rpc_object<Pci::Device>,
|
||||
~Device_component()
|
||||
{
|
||||
_ep->dissolve(&_irq_session);
|
||||
|
||||
for (unsigned i = 0; i < Device::NUM_RESOURCES; i++) {
|
||||
if (_io_port_conn[i])
|
||||
Genode::destroy(_slab_ioport, _io_port_conn[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************
|
||||
@ -139,6 +165,8 @@ class Pci::Device_component : public Genode::Rpc_object<Pci::Device>,
|
||||
return Genode::Irq_session_capability();
|
||||
return _irq_session.cap();
|
||||
}
|
||||
|
||||
Genode::Io_port_session_capability io_port(Genode::uint8_t) override;
|
||||
};
|
||||
|
||||
#endif /* _PCI_DEVICE_COMPONENT_H_ */
|
||||
|
@ -1,6 +1,6 @@
|
||||
TARGET = pci_drv
|
||||
REQUIRES = x86
|
||||
SRC_CC = main.cc irq.cc nonpci_devices.cc session.cc
|
||||
SRC_CC = main.cc irq.cc pci_device.cc nonpci_devices.cc session.cc
|
||||
LIBS = base config
|
||||
|
||||
INC_DIR = $(PRG_DIR)/..
|
||||
|
@ -29,6 +29,7 @@ extern "C" {
|
||||
}
|
||||
|
||||
#include "pci_tree.h"
|
||||
#include "device.h"
|
||||
|
||||
static const bool verbose = false;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user