mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-25 11:12:50 +00:00
parent
b902f42482
commit
4c4e7c64d0
@ -23,7 +23,7 @@ struct Platform::Connection : Genode::Connection<Session>, Client
|
|||||||
{
|
{
|
||||||
Connection()
|
Connection()
|
||||||
:
|
:
|
||||||
Genode::Connection<Session>(session("ram_quota=12K")),
|
Genode::Connection<Session>(session("ram_quota=20K")),
|
||||||
Client(cap())
|
Client(cap())
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
74
repos/os/src/drivers/platform/spec/x86/device_pd.h
Normal file
74
repos/os/src/drivers/platform/spec/x86/device_pd.h
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* \brief Device PD handling for the platform driver
|
||||||
|
* \author Alexander Boettcher
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2014-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 <os/slave.h>
|
||||||
|
|
||||||
|
enum {
|
||||||
|
DEVICE_PD_RAM_QUOTA = 256 * 4096,
|
||||||
|
STACK_SIZE = 2 * sizeof(void *)*1024
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace Platform { class Device_pd_policy; }
|
||||||
|
|
||||||
|
class Platform::Device_pd_policy : public Genode::Slave_policy
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
Genode::Root_capability _cap;
|
||||||
|
Genode::Lock _lock;
|
||||||
|
|
||||||
|
Genode::Slave _device_pd_slave;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
char const **_permitted_services() const
|
||||||
|
{
|
||||||
|
static char const *permitted_services[] = { "LOG", "CAP", "RM", 0 };
|
||||||
|
return permitted_services;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Device_pd_policy(Genode::Rpc_entrypoint &slave_ep)
|
||||||
|
:
|
||||||
|
Slave_policy("device_pd", slave_ep),
|
||||||
|
_lock(Genode::Lock::LOCKED),
|
||||||
|
_device_pd_slave(slave_ep, *this, DEVICE_PD_RAM_QUOTA)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
bool announce_service(const char *service_name,
|
||||||
|
Genode::Root_capability root,
|
||||||
|
Genode::Allocator *alloc,
|
||||||
|
Genode::Server *server)
|
||||||
|
{
|
||||||
|
/* wait for 'platform_drv' to announce the DEVICE_PD service */
|
||||||
|
if (Genode::strcmp(service_name, "DEVICE_PD"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_cap = root;
|
||||||
|
|
||||||
|
_lock.unlock();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Genode::Root_capability root() {
|
||||||
|
if (!_cap.valid())
|
||||||
|
_lock.lock();
|
||||||
|
return _cap;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
@ -16,63 +16,15 @@
|
|||||||
#include <base/sleep.h>
|
#include <base/sleep.h>
|
||||||
#include <cap_session/connection.h>
|
#include <cap_session/connection.h>
|
||||||
|
|
||||||
#include <os/slave.h>
|
|
||||||
#include <os/attached_rom_dataspace.h>
|
#include <os/attached_rom_dataspace.h>
|
||||||
|
|
||||||
#include "pci_session_component.h"
|
#include "pci_session_component.h"
|
||||||
#include "pci_device_config.h"
|
#include "pci_device_config.h"
|
||||||
|
#include "device_pd.h"
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
using namespace Platform;
|
using namespace Platform;
|
||||||
|
|
||||||
class Device_pd_policy : public Genode::Slave_policy
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
Genode::Root_capability _cap;
|
|
||||||
Genode::Lock _lock;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
char const **_permitted_services() const
|
|
||||||
{
|
|
||||||
static char const *permitted_services[] = { "LOG", "CAP", "RM",
|
|
||||||
"CPU", 0 };
|
|
||||||
return permitted_services;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Device_pd_policy(Genode::Rpc_entrypoint &slave_ep)
|
|
||||||
:
|
|
||||||
Slave_policy("device_pd", slave_ep),
|
|
||||||
_lock(Genode::Lock::LOCKED)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
bool announce_service(const char *service_name,
|
|
||||||
Genode::Root_capability root,
|
|
||||||
Genode::Allocator *alloc,
|
|
||||||
Genode::Server *server)
|
|
||||||
{
|
|
||||||
/* wait for 'platform_drv' to announce the DEVICE_PD service */
|
|
||||||
if (Genode::strcmp(service_name, "DEVICE_PD"))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
_cap = root;
|
|
||||||
|
|
||||||
_lock.unlock();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Genode::Root_capability root() {
|
|
||||||
if (!_cap.valid())
|
|
||||||
_lock.lock();
|
|
||||||
return _cap;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
printf("platform driver started\n");
|
printf("platform driver started\n");
|
||||||
@ -80,27 +32,9 @@ int main(int argc, char **argv)
|
|||||||
/*
|
/*
|
||||||
* Initialize server entry point
|
* Initialize server entry point
|
||||||
*/
|
*/
|
||||||
enum {
|
|
||||||
STACK_SIZE = 2 * sizeof(addr_t)*1024,
|
|
||||||
DEVICE_PD_RAM_QUOTA = 256 * 4096,
|
|
||||||
};
|
|
||||||
|
|
||||||
static Cap_connection cap;
|
static Cap_connection cap;
|
||||||
static Rpc_entrypoint ep(&cap, STACK_SIZE, "platform_ep");
|
static Rpc_entrypoint ep(&cap, STACK_SIZE, "platform_ep");
|
||||||
|
|
||||||
/* use 'device_pd' as slave service */
|
|
||||||
Session_capability session_dev_pd;
|
|
||||||
Genode::Root_capability device_pd_root;
|
|
||||||
try {
|
|
||||||
static Rpc_entrypoint device_pd_ep(&cap, STACK_SIZE, "device_pd_slave");
|
|
||||||
static Device_pd_policy device_pd_policy(device_pd_ep);
|
|
||||||
static Genode::Slave device_pd_slave(device_pd_ep, device_pd_policy,
|
|
||||||
DEVICE_PD_RAM_QUOTA);
|
|
||||||
device_pd_root = device_pd_policy.root();
|
|
||||||
} catch (...) {
|
|
||||||
PWRN("PCI device protection domain for IOMMU support is not available");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Use sliced heap to allocate each session component at a separate
|
* Use sliced heap to allocate each session component at a separate
|
||||||
* dataspace.
|
* dataspace.
|
||||||
@ -140,8 +74,7 @@ int main(int argc, char **argv)
|
|||||||
/*
|
/*
|
||||||
* Let the entry point serve the PCI root interface
|
* Let the entry point serve the PCI root interface
|
||||||
*/
|
*/
|
||||||
static Platform::Root root(&ep, &sliced_heap, DEVICE_PD_RAM_QUOTA,
|
static Platform::Root root(&ep, &sliced_heap, report_addr, cap);
|
||||||
device_pd_root, report_addr);
|
|
||||||
|
|
||||||
env()->parent()->announce(ep.manage(&root));
|
env()->parent()->announce(ep.manage(&root));
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include <base/allocator_guard.h>
|
#include <base/allocator_guard.h>
|
||||||
#include <base/rpc_server.h>
|
#include <base/rpc_server.h>
|
||||||
#include <base/tslab.h>
|
#include <base/tslab.h>
|
||||||
|
#include <cap_session/connection.h>
|
||||||
|
|
||||||
#include <ram_session/connection.h>
|
#include <ram_session/connection.h>
|
||||||
#include <root/component.h>
|
#include <root/component.h>
|
||||||
@ -33,6 +34,7 @@
|
|||||||
#include "pci_device_component.h"
|
#include "pci_device_component.h"
|
||||||
#include "pci_config_access.h"
|
#include "pci_config_access.h"
|
||||||
#include "pci_device_pd_ipc.h"
|
#include "pci_device_pd_ipc.h"
|
||||||
|
#include "device_pd.h"
|
||||||
|
|
||||||
namespace Platform {
|
namespace Platform {
|
||||||
bool bus_valid(int bus = 0);
|
bool bus_valid(int bus = 0);
|
||||||
@ -116,8 +118,36 @@ namespace Platform {
|
|||||||
Genode::Allocator_guard _md_alloc;
|
Genode::Allocator_guard _md_alloc;
|
||||||
Genode::Tslab<Device_component, 4096 - 64> _device_slab;
|
Genode::Tslab<Device_component, 4096 - 64> _device_slab;
|
||||||
Genode::List<Device_component> _device_list;
|
Genode::List<Device_component> _device_list;
|
||||||
Device_pd_client _child;
|
|
||||||
Genode::Ram_connection *_ram;
|
struct Devicepd {
|
||||||
|
Platform::Device_pd_policy *policy;
|
||||||
|
Device_pd_client child;
|
||||||
|
|
||||||
|
|
||||||
|
Devicepd (Genode::Rpc_entrypoint &ep,
|
||||||
|
Genode::Allocator_guard &md_alloc)
|
||||||
|
:
|
||||||
|
policy(nullptr),
|
||||||
|
child(Genode::reinterpret_cap_cast<Device_pd>(Genode::Native_capability()))
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
policy = new (md_alloc) Device_pd_policy(ep);
|
||||||
|
|
||||||
|
using Genode::Session_capability;
|
||||||
|
using Genode::Affinity;
|
||||||
|
|
||||||
|
Session_capability session = Genode::Root_client(policy->root()).session("", Affinity());
|
||||||
|
child = Device_pd_client(Genode::reinterpret_cap_cast<Device_pd>(session));
|
||||||
|
} catch (Genode::Rom_connection::Rom_connection_failed) {
|
||||||
|
PWRN("PCI device protection domain for IOMMU support "
|
||||||
|
"is not available");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool valid() { return policy && policy->root().valid(); }
|
||||||
|
} _device_pd;
|
||||||
|
|
||||||
|
Genode::Ram_connection _ram;
|
||||||
Genode::Session_label _label;
|
Genode::Session_label _label;
|
||||||
Genode::Session_policy _policy;
|
Genode::Session_policy _policy;
|
||||||
|
|
||||||
@ -377,15 +407,22 @@ namespace Platform {
|
|||||||
*/
|
*/
|
||||||
Session_component(Genode::Rpc_entrypoint *ep,
|
Session_component(Genode::Rpc_entrypoint *ep,
|
||||||
Genode::Allocator *md_alloc,
|
Genode::Allocator *md_alloc,
|
||||||
Genode::Root_capability &device_pd_root,
|
const char *args,
|
||||||
Genode::Ram_connection *ram,
|
Genode::Rpc_entrypoint &device_pd_ep)
|
||||||
const char *args)
|
|
||||||
:
|
:
|
||||||
_ep(ep),
|
_ep(ep),
|
||||||
_md_alloc(md_alloc, Genode::Arg_string::find_arg(args, "ram_quota").long_value(0)),
|
_md_alloc(md_alloc, Genode::Arg_string::find_arg(args, "ram_quota").long_value(0)),
|
||||||
_device_slab(&_md_alloc), _child(Genode::reinterpret_cap_cast<Device_pd>(Genode::Native_capability())),
|
_device_slab(&_md_alloc),
|
||||||
_ram(ram), _label(args), _policy(_label)
|
_device_pd(device_pd_ep, _md_alloc),
|
||||||
|
/* restrict physical address to 3G on 32bit with device_pd */
|
||||||
|
_ram("dma", 0, (_device_pd.valid() && sizeof(void *) == 4)
|
||||||
|
? 0xc0000000UL : 0x100000000ULL),
|
||||||
|
_label(args), _policy(_label)
|
||||||
{
|
{
|
||||||
|
/* associate _ram session with platform_drv _ram session */
|
||||||
|
_ram.ref_account(Genode::env()->ram_session_cap());
|
||||||
|
Genode::env()->ram_session()->transfer_quota(_ram.cap(), 0x1000);
|
||||||
|
|
||||||
/* non-pci devices */
|
/* non-pci devices */
|
||||||
_policy.for_each_sub_node("device", [&] (Genode::Xml_node device_node) {
|
_policy.for_each_sub_node("device", [&] (Genode::Xml_node device_node) {
|
||||||
try {
|
try {
|
||||||
@ -406,15 +443,6 @@ namespace Platform {
|
|||||||
throw Genode::Root::Unavailable();
|
throw Genode::Root::Unavailable();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (device_pd_root.valid()) {
|
|
||||||
using Genode::Session_capability;
|
|
||||||
using Genode::Affinity;
|
|
||||||
|
|
||||||
Session_capability session = Genode::Root_client(device_pd_root).session("", Affinity());
|
|
||||||
Genode::Capability <Device_pd> cap = Genode::reinterpret_cap_cast<Device_pd>(session);
|
|
||||||
_child = Device_pd_client(cap);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* pci devices */
|
/* pci devices */
|
||||||
_policy.for_each_sub_node("pci", [&] (Genode::Xml_node node) {
|
_policy.for_each_sub_node("pci", [&] (Genode::Xml_node node) {
|
||||||
enum { INVALID_CLASS = 0x1000000U };
|
enum { INVALID_CLASS = 0x1000000U };
|
||||||
@ -671,15 +699,15 @@ namespace Platform {
|
|||||||
|
|
||||||
Io_mem_dataspace_capability io_mem = device->get_config_space();
|
Io_mem_dataspace_capability io_mem = device->get_config_space();
|
||||||
|
|
||||||
if (!_child.valid())
|
if (!_device_pd.child.valid())
|
||||||
return Io_mem_dataspace_capability();
|
return Io_mem_dataspace_capability();
|
||||||
|
|
||||||
_child.assign_pci(io_mem);
|
_device_pd.child.assign_pci(io_mem);
|
||||||
|
|
||||||
for (Rmrr *r = Rmrr::list()->first(); r; r = r->next()) {
|
for (Rmrr *r = Rmrr::list()->first(); r; r = r->next()) {
|
||||||
Io_mem_dataspace_capability rmrr_cap = r->match(device->config());
|
Io_mem_dataspace_capability rmrr_cap = r->match(device->config());
|
||||||
if (rmrr_cap.valid())
|
if (rmrr_cap.valid())
|
||||||
_child.attach_dma_mem(rmrr_cap);
|
_device_pd.child.attach_dma_mem(rmrr_cap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -709,7 +737,7 @@ namespace Platform {
|
|||||||
throw Device::Quota_exceeded();
|
throw Device::Quota_exceeded();
|
||||||
|
|
||||||
Genode::Ram_session * const rs = Genode::env()->ram_session();
|
Genode::Ram_session * const rs = Genode::env()->ram_session();
|
||||||
if (rs->transfer_quota(_ram->cap(), size)) {
|
if (rs->transfer_quota(_ram.cap(), size)) {
|
||||||
_md_alloc.upgrade(size);
|
_md_alloc.upgrade(size);
|
||||||
return Ram_capability();
|
return Ram_capability();
|
||||||
}
|
}
|
||||||
@ -717,20 +745,20 @@ namespace Platform {
|
|||||||
Ram_capability ram_cap;
|
Ram_capability ram_cap;
|
||||||
try {
|
try {
|
||||||
ram_cap = Genode::retry<Genode::Ram_session::Out_of_metadata>(
|
ram_cap = Genode::retry<Genode::Ram_session::Out_of_metadata>(
|
||||||
[&] () { return _ram->alloc(size, Genode::UNCACHED); },
|
[&] () { return _ram.alloc(size, Genode::UNCACHED); },
|
||||||
[&] () { Genode::env()->parent()->upgrade(_ram->cap(), "ram_quota=4K"); });
|
[&] () { Genode::env()->parent()->upgrade(_ram.cap(), "ram_quota=4K"); });
|
||||||
} catch (Genode::Ram_session::Quota_exceeded) { }
|
} catch (Genode::Ram_session::Quota_exceeded) { }
|
||||||
|
|
||||||
if (!ram_cap.valid()) {
|
if (!ram_cap.valid()) {
|
||||||
_ram->transfer_quota(Genode::env()->ram_session_cap(), size);
|
_ram.transfer_quota(Genode::env()->ram_session_cap(), size);
|
||||||
_md_alloc.upgrade(size);
|
_md_alloc.upgrade(size);
|
||||||
return ram_cap;
|
return ram_cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_child.valid())
|
if (!_device_pd.child.valid())
|
||||||
return ram_cap;
|
return ram_cap;
|
||||||
|
|
||||||
_child.attach_dma_mem(ram_cap);
|
_device_pd.child.attach_dma_mem(ram_cap);
|
||||||
|
|
||||||
return ram_cap;
|
return ram_cap;
|
||||||
}
|
}
|
||||||
@ -738,7 +766,7 @@ namespace Platform {
|
|||||||
void free_dma_buffer(Ram_capability ram)
|
void free_dma_buffer(Ram_capability ram)
|
||||||
{
|
{
|
||||||
if (ram.valid())
|
if (ram.valid())
|
||||||
_ram->free(ram);
|
_ram.free(ram);
|
||||||
}
|
}
|
||||||
|
|
||||||
Device_capability device(String const &name) override;
|
Device_capability device(String const &name) override;
|
||||||
@ -749,9 +777,7 @@ class Platform::Root : public Genode::Root_component<Session_component>
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Genode::Root_capability _device_pd_root;
|
Genode::Rpc_entrypoint _device_pd_ep;
|
||||||
/* Ram_session for allocation of dma capable dataspaces */
|
|
||||||
Genode::Ram_connection _ram;
|
|
||||||
|
|
||||||
void _parse_report_rom(const char * acpi_rom)
|
void _parse_report_rom(const char * acpi_rom)
|
||||||
{
|
{
|
||||||
@ -884,8 +910,7 @@ class Platform::Root : public Genode::Root_component<Session_component>
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return new (md_alloc()) Session_component(ep(), md_alloc(),
|
return new (md_alloc()) Session_component(ep(), md_alloc(),
|
||||||
_device_pd_root,
|
args, _device_pd_ep);
|
||||||
&_ram, args);
|
|
||||||
} catch (Genode::Session_policy::No_policy_defined) {
|
} catch (Genode::Session_policy::No_policy_defined) {
|
||||||
PERR("Invalid session request, no matching policy for '%s'",
|
PERR("Invalid session request, no matching policy for '%s'",
|
||||||
Genode::Session_label(args).string());
|
Genode::Session_label(args).string());
|
||||||
@ -900,7 +925,6 @@ class Platform::Root : public Genode::Root_component<Session_component>
|
|||||||
s->upgrade_ram_quota(ram_quota);
|
s->upgrade_ram_quota(ram_quota);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -912,14 +936,10 @@ class Platform::Root : public Genode::Root_component<Session_component>
|
|||||||
* components and PCI-device components
|
* components and PCI-device components
|
||||||
*/
|
*/
|
||||||
Root(Genode::Rpc_entrypoint *ep, Genode::Allocator *md_alloc,
|
Root(Genode::Rpc_entrypoint *ep, Genode::Allocator *md_alloc,
|
||||||
Genode::size_t pci_device_pd_ram_quota,
|
const char *acpi_rom, Genode::Cap_connection &cap)
|
||||||
Genode::Root_capability &device_pd_root, const char *acpi_rom)
|
|
||||||
:
|
:
|
||||||
Genode::Root_component<Session_component>(ep, md_alloc),
|
Genode::Root_component<Session_component>(ep, md_alloc),
|
||||||
_device_pd_root(device_pd_root),
|
_device_pd_ep(&cap, STACK_SIZE, "device_pd_slave")
|
||||||
/* restrict physical address to 3G on 32bit with device_pd */
|
|
||||||
_ram("dma", 0, (device_pd_root.valid() && sizeof(void *) == 4) ?
|
|
||||||
0xc0000000UL : 0x100000000ULL)
|
|
||||||
{
|
{
|
||||||
/* enforce initial bus scan */
|
/* enforce initial bus scan */
|
||||||
bus_valid();
|
bus_valid();
|
||||||
@ -931,9 +951,5 @@ class Platform::Root : public Genode::Root_component<Session_component>
|
|||||||
PERR("PCI config space data could not be parsed.");
|
PERR("PCI config space data could not be parsed.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* associate _ram session with ram_session of process */
|
|
||||||
_ram.ref_account(Genode::env()->ram_session_cap());
|
|
||||||
Genode::env()->ram_session()->transfer_quota(_ram.cap(), 0x1000);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user