mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-12 13:48:30 +00:00
parent
e4d663cf41
commit
8743575dcf
@ -16,17 +16,28 @@
|
||||
|
||||
#include <base/rpc.h>
|
||||
#include <base/signal.h>
|
||||
#include <base/exception.h>
|
||||
#include <io_mem_session/io_mem_session.h>
|
||||
#include <irq_session/capability.h>
|
||||
#include <ram_session/ram_session.h>
|
||||
|
||||
/* os includes */
|
||||
#include <platform/device.h>
|
||||
|
||||
|
||||
namespace Pci { struct Device; }
|
||||
|
||||
|
||||
struct Pci::Device : Platform::Device
|
||||
{
|
||||
/*********************
|
||||
** Exception types **
|
||||
*********************/
|
||||
|
||||
class Alloc_failed : public Genode::Exception { };
|
||||
class Quota_exceeded : public Alloc_failed { };
|
||||
|
||||
|
||||
class Resource
|
||||
{
|
||||
private:
|
||||
|
@ -14,9 +14,11 @@
|
||||
#ifndef _INCLUDE__PCI_SESSION__CLIENT_H_
|
||||
#define _INCLUDE__PCI_SESSION__CLIENT_H_
|
||||
|
||||
#include <pci_session/capability.h>
|
||||
#include <base/rpc_client.h>
|
||||
|
||||
#include <pci_device/client.h>
|
||||
#include <pci_session/capability.h>
|
||||
|
||||
namespace Pci { struct Session_client; }
|
||||
|
||||
|
||||
@ -45,6 +47,9 @@ struct Pci::Session_client : public Genode::Rpc_client<Session>
|
||||
|
||||
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); }
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__PCI_SESSION__CLIENT_H_ */
|
||||
|
@ -14,13 +14,16 @@
|
||||
#ifndef _INCLUDE__PCI_SESSION__PCI_SESSION_H_
|
||||
#define _INCLUDE__PCI_SESSION__PCI_SESSION_H_
|
||||
|
||||
#include <pci_device/pci_device.h>
|
||||
/* base */
|
||||
#include <session/session.h>
|
||||
#include <ram_session/ram_session.h>
|
||||
|
||||
/* os */
|
||||
#include <pci_device/pci_device.h>
|
||||
|
||||
namespace Pci {
|
||||
|
||||
typedef Genode::Capability<Device> Device_capability;
|
||||
typedef Genode::Capability<Pci::Device> Device_capability;
|
||||
|
||||
struct Session;
|
||||
}
|
||||
@ -61,9 +64,16 @@ struct Pci::Session : Genode::Session
|
||||
*/
|
||||
virtual Genode::Io_mem_dataspace_capability config_extended(Device_capability) = 0;
|
||||
|
||||
typedef Genode::Rpc_in_buffer<8> String;
|
||||
|
||||
/**
|
||||
* Allocate memory suitable for DMA.
|
||||
* 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;
|
||||
|
||||
/**
|
||||
@ -71,6 +81,7 @@ struct Pci::Session : Genode::Session
|
||||
*/
|
||||
virtual void free_dma_buffer(Genode::Ram_dataspace_capability) = 0;
|
||||
|
||||
|
||||
/*********************
|
||||
** RPC declaration **
|
||||
*********************/
|
||||
@ -88,10 +99,14 @@ struct Pci::Session : Genode::Session
|
||||
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(Pci::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_alloc_dma_buffer, Rpc_free_dma_buffer,
|
||||
Rpc_device);
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__PCI_SESSION__PCI_SESSION_H_ */
|
||||
|
93
repos/os/src/drivers/pci/nonpci_devices.cc
Normal file
93
repos/os/src/drivers/pci/nonpci_devices.cc
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* \brief Non PCI devices, e.g. PS2
|
||||
* \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 <irq_session/connection.h>
|
||||
#include "pci_session_component.h"
|
||||
|
||||
|
||||
namespace Nonpci { class Ps2; }
|
||||
|
||||
class Nonpci::Ps2 : public Pci::Device_component
|
||||
{
|
||||
private:
|
||||
|
||||
enum {
|
||||
IRQ_KEYBOARD = 1,
|
||||
IRQ_MOUSE = 12,
|
||||
};
|
||||
|
||||
Genode::Irq_connection _irq_mouse;
|
||||
|
||||
public:
|
||||
|
||||
Ps2(Genode::Rpc_entrypoint * ep, Pci::Session_component * session)
|
||||
:
|
||||
Pci::Device_component(ep, IRQ_KEYBOARD),
|
||||
_irq_mouse(IRQ_MOUSE)
|
||||
{ }
|
||||
|
||||
Genode::Irq_session_capability irq(Genode::uint8_t virt_irq) override
|
||||
{
|
||||
switch (virt_irq) {
|
||||
case 0:
|
||||
return Device_component::irq(virt_irq);
|
||||
case 1:
|
||||
return _irq_mouse.cap();
|
||||
default:
|
||||
return Genode::Irq_session_capability();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* PCI session component devices which are non PCI devices, e.g. PS2
|
||||
*/
|
||||
Pci::Device_capability Pci::Session_component::device(String const &name) {
|
||||
|
||||
if (!name.is_valid_string())
|
||||
return Device_capability();
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
char const * device_name = name.string();
|
||||
const char * devices [] = { "PS2" };
|
||||
unsigned devices_i = 0;
|
||||
|
||||
for (; devices_i < sizeof(devices) / sizeof(devices[0]); devices_i++)
|
||||
if (!strcmp(device_name, devices[devices_i]))
|
||||
break;
|
||||
|
||||
if (devices_i >= sizeof(devices) / sizeof(devices[0])) {
|
||||
PERR("unknown '%s' device name", device_name);
|
||||
return Device_capability();
|
||||
}
|
||||
|
||||
try {
|
||||
Device_component * dev = nullptr;
|
||||
|
||||
switch(devices_i) {
|
||||
case 0:
|
||||
dev = new (_md_alloc) Nonpci::Ps2(_ep, this);
|
||||
break;
|
||||
default:
|
||||
return Device_capability();
|
||||
}
|
||||
|
||||
_device_list.insert(dev);
|
||||
return _ep->manage(dev);
|
||||
} catch (Genode::Allocator::Out_of_memory) {
|
||||
throw Pci::Device::Quota_exceeded();
|
||||
} catch (Genode::Parent::Service_denied) {
|
||||
return Device_capability();
|
||||
}
|
||||
}
|
@ -57,6 +57,16 @@ class Pci::Device_component : public Genode::Rpc_object<Pci::Device>,
|
||||
_ep->manage(&_irq_session);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for non PCI devices
|
||||
*/
|
||||
Device_component(Genode::Rpc_entrypoint *ep, unsigned irq)
|
||||
:
|
||||
_config_space(~0UL), _io_mem(0), _ep(ep), _irq_session(irq)
|
||||
{
|
||||
_ep->manage(&_irq_session);
|
||||
}
|
||||
|
||||
/**
|
||||
* De-constructor
|
||||
*/
|
||||
|
@ -14,65 +14,26 @@
|
||||
#ifndef _PCI_SESSION_COMPONENT_H_
|
||||
#define _PCI_SESSION_COMPONENT_H_
|
||||
|
||||
/* base */
|
||||
#include <base/rpc_server.h>
|
||||
#include <pci_session/pci_session.h>
|
||||
#include <ram_session/connection.h>
|
||||
#include <root/component.h>
|
||||
|
||||
/* os */
|
||||
#include <io_mem_session/connection.h>
|
||||
|
||||
#include <os/config.h>
|
||||
#include <pci_session/pci_session.h>
|
||||
|
||||
/* local */
|
||||
#include "pci_device_component.h"
|
||||
#include "pci_config_access.h"
|
||||
#include "pci_device_pd_ipc.h"
|
||||
|
||||
namespace Pci {
|
||||
bool bus_valid(int bus = 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if given PCI bus was found on initial scan
|
||||
*
|
||||
* This tremendously speeds up further scans by other drivers.
|
||||
*/
|
||||
bool bus_valid(int bus = 0)
|
||||
{
|
||||
struct Valid_buses
|
||||
{
|
||||
bool valid[Device_config::MAX_BUSES];
|
||||
|
||||
void scan_bus(Config_access &config_access, int bus = 0)
|
||||
{
|
||||
for (int dev = 0; dev < Device_config::MAX_DEVICES; ++dev) {
|
||||
for (int fun = 0; fun < Device_config::MAX_FUNCTIONS; ++fun) {
|
||||
|
||||
/* read config space */
|
||||
Device_config config(bus, dev, fun, &config_access);
|
||||
|
||||
if (!config.valid())
|
||||
continue;
|
||||
|
||||
/*
|
||||
* There is at least one device on the current bus, so
|
||||
* we mark it as valid.
|
||||
*/
|
||||
valid[bus] = true;
|
||||
|
||||
/* scan behind bridge */
|
||||
if (config.is_pci_bridge()) {
|
||||
int sub_bus = config.read(&config_access,
|
||||
0x19, Device::ACCESS_8BIT);
|
||||
scan_bus(config_access, sub_bus);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Valid_buses() { Config_access c; scan_bus(c); }
|
||||
};
|
||||
|
||||
static Valid_buses buses;
|
||||
|
||||
return buses.valid[bus];
|
||||
}
|
||||
namespace Pci {
|
||||
|
||||
class Session_component : public Genode::Rpc_object<Session>
|
||||
{
|
||||
@ -335,6 +296,8 @@ namespace Pci {
|
||||
if (ram.valid())
|
||||
_ram->free(ram);
|
||||
}
|
||||
|
||||
Device_capability device(String const &name) override;
|
||||
};
|
||||
|
||||
|
||||
|
60
repos/os/src/drivers/pci/session.cc
Normal file
60
repos/os/src/drivers/pci/session.cc
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* \brief PCI-session component
|
||||
* \author Norman Feske
|
||||
* \date 2008-01-28
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "pci_session_component.h"
|
||||
|
||||
/**
|
||||
* Check if given PCI bus was found on initial scan
|
||||
*
|
||||
* This tremendously speeds up further scans by other drivers.
|
||||
*/
|
||||
bool Pci::bus_valid(int bus)
|
||||
{
|
||||
struct Valid_buses
|
||||
{
|
||||
bool valid[Device_config::MAX_BUSES];
|
||||
|
||||
void scan_bus(Config_access &config_access, int bus = 0)
|
||||
{
|
||||
for (int dev = 0; dev < Device_config::MAX_DEVICES; ++dev) {
|
||||
for (int fun = 0; fun < Device_config::MAX_FUNCTIONS; ++fun) {
|
||||
|
||||
/* read config space */
|
||||
Device_config config(bus, dev, fun, &config_access);
|
||||
|
||||
if (!config.valid())
|
||||
continue;
|
||||
|
||||
/*
|
||||
* There is at least one device on the current bus, so
|
||||
* we mark it as valid.
|
||||
*/
|
||||
valid[bus] = true;
|
||||
|
||||
/* scan behind bridge */
|
||||
if (config.is_pci_bridge()) {
|
||||
int sub_bus = config.read(&config_access,
|
||||
0x19, Device::ACCESS_8BIT);
|
||||
scan_bus(config_access, sub_bus);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Valid_buses() { Config_access c; scan_bus(c); }
|
||||
};
|
||||
|
||||
static Valid_buses buses;
|
||||
|
||||
return buses.valid[bus];
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
TARGET = pci_drv
|
||||
REQUIRES = x86
|
||||
SRC_CC = main.cc irq.cc
|
||||
SRC_CC = main.cc irq.cc nonpci_devices.cc session.cc
|
||||
LIBS = base config
|
||||
|
||||
INC_DIR = $(PRG_DIR)/..
|
||||
|
Loading…
x
Reference in New Issue
Block a user