x86/platform_session: import Genode namespace

This change avoids many repetetive Genode:: prefixes, making the code
easier to read. The patch also includes a few consistency fixes
regarding include guards and file headers. It also renames
Platform_device::String to Platform_device::Device:name.

Issue #2243
This commit is contained in:
Norman Feske 2021-04-08 16:27:52 +02:00
parent a839b4f0bb
commit 53e44f8bfd
19 changed files with 543 additions and 604 deletions

View File

@ -22,10 +22,10 @@
namespace Platform { struct Device_client; } namespace Platform { struct Device_client; }
struct Platform::Device_client : public Genode::Rpc_client<Device> struct Platform::Device_client : public Rpc_client<Device>
{ {
Device_client(Device_capability device) Device_client(Device_capability device)
: Genode::Rpc_client<Device>(device) { } : Rpc_client<Device>(device) { }
void bus_address(unsigned char *bus, unsigned char *dev, unsigned char *fn) override { void bus_address(unsigned char *bus, unsigned char *dev, unsigned char *fn) override {
call<Rpc_bus_address>(bus, dev, fn); } call<Rpc_bus_address>(bus, dev, fn); }
@ -48,16 +48,16 @@ struct Platform::Device_client : public Genode::Rpc_client<Device>
void config_write(unsigned char address, unsigned value, Access_size size) override { void config_write(unsigned char address, unsigned value, Access_size size) override {
call<Rpc_config_write>(address, value, size); } call<Rpc_config_write>(address, value, size); }
Genode::Irq_session_capability irq(Genode::uint8_t id) override { Irq_session_capability irq(uint8_t id) override {
return call<Rpc_irq>(id); } return call<Rpc_irq>(id); }
Genode::Io_port_session_capability io_port(Genode::uint8_t id) override { Io_port_session_capability io_port(uint8_t id) override {
return call<Rpc_io_port>(id); } return call<Rpc_io_port>(id); }
Genode::Io_mem_session_capability io_mem(Genode::uint8_t id, Io_mem_session_capability io_mem(uint8_t id,
Genode::Cache cache = Genode::Cache::UNCACHED, Cache cache = Cache::UNCACHED,
Genode::addr_t offset = 0, addr_t offset = 0,
Genode::size_t size = ~0UL) override { size_t size = ~0UL) override {
return call<Rpc_io_mem>(id, cache, offset, size); } return call<Rpc_io_mem>(id, cache, offset, size); }
}; };

View File

@ -14,6 +14,7 @@
#ifndef _INCLUDE__SPEC__X86__PLATFORM_DEVICE__PLATFORM_DEVICE_H_ #ifndef _INCLUDE__SPEC__X86__PLATFORM_DEVICE__PLATFORM_DEVICE_H_
#define _INCLUDE__SPEC__X86__PLATFORM_DEVICE__PLATFORM_DEVICE_H_ #define _INCLUDE__SPEC__X86__PLATFORM_DEVICE__PLATFORM_DEVICE_H_
/* Genode includes */
#include <base/rpc.h> #include <base/rpc.h>
#include <base/signal.h> #include <base/signal.h>
#include <base/exception.h> #include <base/exception.h>
@ -27,10 +28,9 @@
namespace Platform { namespace Platform {
struct Device; using namespace Genode;
using Genode::Out_of_caps; struct Device;
using Genode::Out_of_ram;
} }
@ -178,7 +178,7 @@ struct Platform::Device : Platform::Abstract_device
* \throw Out_of_ram * \throw Out_of_ram
* \throw Out_of_caps * \throw Out_of_caps
*/ */
virtual Genode::Io_port_session_capability io_port(Genode::uint8_t id) = 0; virtual Io_port_session_capability io_port(uint8_t id) = 0;
/* /*
* The base classes are defined as follows: * The base classes are defined as follows:
@ -214,9 +214,9 @@ struct Platform::Device : Platform::Abstract_device
* virtual one usable with the io_port and io_mem methods. The virtual id * virtual one usable with the io_port and io_mem methods. The virtual id
* is solely valid for the specific BAR type. * is solely valid for the specific BAR type.
*/ */
Genode::uint8_t phys_bar_to_virt(Genode::uint8_t phys_bar) uint8_t phys_bar_to_virt(uint8_t phys_bar)
{ {
Genode::uint8_t virt_io_port = 0, virt_io_mem = 0; uint8_t virt_io_port = 0, virt_io_mem = 0;
for (unsigned i = 0; i < phys_bar; i++) { for (unsigned i = 0; i < phys_bar; i++) {
Resource::Type type = resource(i).type(); Resource::Type type = resource(i).type();
@ -245,14 +245,13 @@ struct Platform::Device : Platform::Abstract_device
GENODE_RPC_THROW(Rpc_config_write, void, config_write, GENODE_RPC_THROW(Rpc_config_write, void, config_write,
GENODE_TYPE_LIST(Out_of_ram, Out_of_caps), GENODE_TYPE_LIST(Out_of_ram, Out_of_caps),
unsigned char, unsigned, Access_size); unsigned char, unsigned, Access_size);
GENODE_RPC(Rpc_irq, Genode::Irq_session_capability, irq, Genode::uint8_t); GENODE_RPC(Rpc_irq, Irq_session_capability, irq, uint8_t);
GENODE_RPC_THROW(Rpc_io_port, Genode::Io_port_session_capability, io_port, GENODE_RPC_THROW(Rpc_io_port, Io_port_session_capability, io_port,
GENODE_TYPE_LIST(Out_of_ram, Out_of_caps), GENODE_TYPE_LIST(Out_of_ram, Out_of_caps),
Genode::uint8_t); uint8_t);
GENODE_RPC_THROW(Rpc_io_mem, Genode::Io_mem_session_capability, io_mem, GENODE_RPC_THROW(Rpc_io_mem, Io_mem_session_capability, io_mem,
GENODE_TYPE_LIST(Out_of_ram, Out_of_caps), GENODE_TYPE_LIST(Out_of_ram, Out_of_caps),
Genode::uint8_t, Genode::Cache, uint8_t, Cache, addr_t, size_t);
Genode::addr_t, Genode::size_t);
GENODE_RPC_INTERFACE(Rpc_bus_address, Rpc_vendor_id, Rpc_device_id, GENODE_RPC_INTERFACE(Rpc_bus_address, Rpc_vendor_id, Rpc_device_id,
Rpc_class_code, Rpc_resource, Rpc_config_read, Rpc_class_code, Rpc_resource, Rpc_config_read,

View File

@ -11,20 +11,19 @@
* under the terms of the GNU Affero General Public License version 3. * under the terms of the GNU Affero General Public License version 3.
*/ */
#pragma once #ifndef _INCLUDE__SPEC__X86__PLATFORM_SESSION_H_
#define _INCLUDE__SPEC__X86__PLATFORM_SESSION_H_
#include <base/rpc_client.h> #include <base/rpc_client.h>
#include <platform_device/client.h> #include <platform_device/client.h>
#include <platform_session/capability.h> #include <platform_session/capability.h>
namespace Platform { struct Client; } namespace Platform { struct Client; }
struct Platform::Client : public Genode::Rpc_client<Session> struct Platform::Client : public Rpc_client<Session>
{ {
Client(Session_capability session) Client(Session_capability session) : Rpc_client<Session>(session) { }
: Genode::Rpc_client<Session>(session) { }
Device_capability first_device(unsigned device_class = 0, Device_capability first_device(unsigned device_class = 0,
unsigned class_mask = 0) override { unsigned class_mask = 0) override {
@ -38,15 +37,17 @@ struct Platform::Client : public Genode::Rpc_client<Session>
void release_device(Device_capability device) override { void release_device(Device_capability device) override {
call<Rpc_release_device>(device); } call<Rpc_release_device>(device); }
Genode::Ram_dataspace_capability alloc_dma_buffer(Genode::size_t size) override { Ram_dataspace_capability alloc_dma_buffer(size_t size) override {
return call<Rpc_alloc_dma_buffer>(size); } return call<Rpc_alloc_dma_buffer>(size); }
void free_dma_buffer(Genode::Ram_dataspace_capability cap) override { void free_dma_buffer(Ram_dataspace_capability cap) override {
call<Rpc_free_dma_buffer>(cap); } call<Rpc_free_dma_buffer>(cap); }
Genode::addr_t dma_addr(Genode::Ram_dataspace_capability cap) override { addr_t dma_addr(Ram_dataspace_capability cap) override {
return call<Rpc_dma_addr>(cap); } return call<Rpc_dma_addr>(cap); }
Device_capability device(String const &device) override { Device_capability device(Device_name const &device) override {
return call<Rpc_device>(device); } return call<Rpc_device>(device); }
}; };
#endif /* _INCLUDE__SPEC__X86__PLATFORM_SESSION_H_ */

View File

@ -11,7 +11,8 @@
* under the terms of the GNU Affero General Public License version 3. * under the terms of the GNU Affero General Public License version 3.
*/ */
#pragma once #ifndef _INCLUDE__SPEC__X86__PLATFORM_SESSION__CONNECTION_H_
#define _INCLUDE__SPEC__X86__PLATFORM_SESSION__CONNECTION_H_
#include <util/retry.h> #include <util/retry.h>
#include <base/connection.h> #include <base/connection.h>
@ -25,7 +26,7 @@ struct Platform::Connection : Genode::Connection<Session>, Client
/** /**
* Constructor * Constructor
*/ */
Connection(Genode::Env &env) Connection(Env &env)
: :
Genode::Connection<Session>(env, session(env.parent(), Genode::Connection<Session>(env, session(env.parent(),
"ram_quota=16K, cap_quota=%u", "ram_quota=16K, cap_quota=%u",
@ -36,9 +37,9 @@ struct Platform::Connection : Genode::Connection<Session>, Client
template <typename FUNC> template <typename FUNC>
auto with_upgrade(FUNC func) -> decltype(func()) auto with_upgrade(FUNC func) -> decltype(func())
{ {
return Genode::retry<Genode::Out_of_ram>( return retry<Out_of_ram>(
[&] () { [&] () {
return Genode::retry<Genode::Out_of_caps>( return retry<Out_of_caps>(
[&] () { return func(); }, [&] () { return func(); },
[&] () { this->upgrade_caps(2); }); [&] () { this->upgrade_caps(2); });
}, },
@ -46,3 +47,5 @@ struct Platform::Connection : Genode::Connection<Session>, Client
); );
} }
}; };
#endif /* _INCLUDE__SPEC__X86__PLATFORM_SESSION__CONNECTION_H_ */

View File

@ -27,12 +27,6 @@ namespace Platform { struct Session; }
struct Platform::Session : Genode::Session struct Platform::Session : Genode::Session
{ {
/*********************
** Exception types **
*********************/
class Fatal : public Genode::Out_of_ram { };
/** /**
* \noapi * \noapi
*/ */
@ -65,27 +59,27 @@ struct Platform::Session : Genode::Session
*/ */
virtual void release_device(Device_capability device) = 0; virtual void release_device(Device_capability device) = 0;
typedef Genode::Rpc_in_buffer<8> String; typedef Rpc_in_buffer<8> Device_name;
/** /**
* Provide non-PCI device known by unique name * Provide non-PCI device known by unique name
*/ */
virtual Device_capability device(String const &string) = 0; virtual Device_capability device(Device_name const &string) = 0;
/** /**
* Allocate memory suitable for DMA * Allocate memory suitable for DMA
*/ */
virtual Genode::Ram_dataspace_capability alloc_dma_buffer(Genode::size_t) = 0; virtual Ram_dataspace_capability alloc_dma_buffer(size_t) = 0;
/** /**
* Free previously allocated DMA memory * Free previously allocated DMA memory
*/ */
virtual void free_dma_buffer(Genode::Ram_dataspace_capability) = 0; virtual void free_dma_buffer(Ram_dataspace_capability) = 0;
/** /**
* Return the bus address of the previously allocated DMA memory * Return the bus address of the previously allocated DMA memory
*/ */
virtual Genode::addr_t dma_addr(Genode::Ram_dataspace_capability) = 0; virtual addr_t dma_addr(Ram_dataspace_capability) = 0;
/********************* /*********************
** RPC declaration ** ** RPC declaration **
@ -98,17 +92,16 @@ struct Platform::Session : Genode::Session
GENODE_TYPE_LIST(Out_of_ram, Out_of_caps), GENODE_TYPE_LIST(Out_of_ram, Out_of_caps),
Device_capability, unsigned, unsigned); Device_capability, unsigned, unsigned);
GENODE_RPC(Rpc_release_device, void, release_device, Device_capability); GENODE_RPC(Rpc_release_device, void, release_device, Device_capability);
GENODE_RPC_THROW(Rpc_alloc_dma_buffer, Genode::Ram_dataspace_capability, GENODE_RPC_THROW(Rpc_alloc_dma_buffer, Ram_dataspace_capability,
alloc_dma_buffer, alloc_dma_buffer,
GENODE_TYPE_LIST(Out_of_ram, Out_of_caps, Fatal), GENODE_TYPE_LIST(Out_of_ram, Out_of_caps),
Genode::size_t); size_t);
GENODE_RPC(Rpc_free_dma_buffer, void, free_dma_buffer, GENODE_RPC(Rpc_free_dma_buffer, void, free_dma_buffer,
Genode::Ram_dataspace_capability); Ram_dataspace_capability);
GENODE_RPC(Rpc_dma_addr, Genode::addr_t, dma_addr, GENODE_RPC(Rpc_dma_addr, addr_t, dma_addr, Ram_dataspace_capability);
Genode::Ram_dataspace_capability);
GENODE_RPC_THROW(Rpc_device, Device_capability, device, GENODE_RPC_THROW(Rpc_device, Device_capability, device,
GENODE_TYPE_LIST(Out_of_ram, Out_of_caps), GENODE_TYPE_LIST(Out_of_ram, Out_of_caps),
String const &); Device_name const &);
GENODE_RPC_INTERFACE(Rpc_first_device, Rpc_next_device, GENODE_RPC_INTERFACE(Rpc_first_device, Rpc_next_device,
Rpc_release_device, Rpc_alloc_dma_buffer, Rpc_release_device, Rpc_alloc_dma_buffer,

View File

@ -20,8 +20,8 @@
#include "device_pd.h" #include "device_pd.h"
void Platform::Device_pd::attach_dma_mem(Genode::Dataspace_capability ds_cap, void Platform::Device_pd::attach_dma_mem(Dataspace_capability ds_cap,
Genode::addr_t const dma_addr) addr_t const dma_addr)
{ {
using namespace Genode; using namespace Genode;
@ -52,19 +52,15 @@ void Platform::Device_pd::attach_dma_mem(Genode::Dataspace_capability ds_cap,
if (page != ~0UL) if (page != ~0UL)
_address_space.detach(page); _address_space.detach(page);
Genode::error(_label, ": attachment of DMA memory @ ", error(_label, ": attachment of DMA memory @ ",
Genode::Hex(dma_addr), "+", Genode::Hex(size), " " Hex(dma_addr), "+", Hex(size), " " "failed page=", Hex(page));
"failed page=", Genode::Hex(page));
return; return;
} }
} }
void Platform::Device_pd::assign_pci(Genode::Io_mem_dataspace_capability const io_mem_cap, void Platform::Device_pd::assign_pci(Io_mem_dataspace_capability const io_mem_cap,
Genode::addr_t const offset, addr_t const offset, uint16_t const rid)
Genode::uint16_t const rid)
{ {
using namespace Genode;
Dataspace_client ds_client(io_mem_cap); Dataspace_client ds_client(io_mem_cap);
addr_t page = _address_space.attach(io_mem_cap, 0x1000, offset); addr_t page = _address_space.attach(io_mem_cap, 0x1000, offset);
@ -79,12 +75,11 @@ void Platform::Device_pd::assign_pci(Genode::Io_mem_dataspace_capability const i
/* utility to print rid value */ /* utility to print rid value */
struct Rid struct Rid
{ {
Genode::uint16_t const v; uint16_t const v;
explicit Rid(Genode::uint16_t rid) : v(rid) { } explicit Rid(uint16_t rid) : v(rid) { }
void print(Genode::Output &out) const void print(Output &out) const
{ {
using Genode::print; using Genode::print;
using Genode::Hex;
print(out, Hex((uint8_t)(v >> 8), Hex::Prefix::OMIT_PREFIX, Hex::PAD), ":", print(out, Hex((uint8_t)(v >> 8), Hex::Prefix::OMIT_PREFIX, Hex::PAD), ":",
Hex((uint8_t)((v >> 3) & 0x1f), Hex::Prefix::OMIT_PREFIX, Hex::PAD), ".", Hex((uint8_t)((v >> 3) & 0x1f), Hex::Prefix::OMIT_PREFIX, Hex::PAD), ".",
Hex(v & 0x7, Hex::Prefix::OMIT_PREFIX)); Hex(v & 0x7, Hex::Prefix::OMIT_PREFIX));
@ -93,10 +88,10 @@ void Platform::Device_pd::assign_pci(Genode::Io_mem_dataspace_capability const i
/* try to assign pci device to this protection domain */ /* try to assign pci device to this protection domain */
if (!_pd.assign_pci(page, rid)) if (!_pd.assign_pci(page, rid))
Genode::error(_label, ": assignment of PCI device ", Rid(rid), " failed ", error(_label, ": assignment of PCI device ", Rid(rid), " failed ",
"virt=", Genode::Hex(page)); "virt=", Hex(page));
else else
Genode::log(_label,": assignment of PCI device ", Rid(rid), " succeeded"); log(_label,": assignment of PCI device ", Rid(rid), " succeeded");
/* we don't need the mapping anymore */ /* we don't need the mapping anymore */
_address_space.detach(page); _address_space.detach(page);

View File

@ -1,35 +1,38 @@
/* /*
* \brief Device PD handling for the platform driver * \brief Device PD handling for the platform driver
* \author Alexander Boettcher * \author Alexander Boettcher
* \date 2015-11-05
*/ */
/* /*
* Copyright (C) 2014-2017 Genode Labs GmbH * Copyright (C) 2015-2021 Genode Labs GmbH
* *
* This file is part of the Genode OS framework, which is distributed * This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3. * under the terms of the GNU Affero General Public License version 3.
*/ */
#ifndef _DEVICE_PD_H_
#pragma once #define _DEVICE_PD_H_
/* base */ /* base */
#include <base/env.h> #include <base/env.h>
#include <base/quota_guard.h> #include <base/quota_guard.h>
#include <region_map/client.h> #include <region_map/client.h>
#include <pd_session/connection.h> #include <pd_session/connection.h>
/* os */
#include <io_mem_session/connection.h> #include <io_mem_session/connection.h>
/* os */
#include <platform_session/platform_session.h>
namespace Platform { class Device_pd; } namespace Platform { class Device_pd; }
class Platform::Device_pd class Platform::Device_pd
{ {
private: private:
Genode::Pd_connection _pd; Pd_connection _pd;
Genode::Session_label const &_label; Session_label const &_label;
/** /**
* Custom handling of PD-session depletion during attach operations * Custom handling of PD-session depletion during attach operations
@ -39,32 +42,32 @@ class Platform::Device_pd
* want to issue resource requests but let the platform driver reflect this * want to issue resource requests but let the platform driver reflect this
* condition to its client. * condition to its client.
*/ */
struct Expanding_region_map_client : Genode::Region_map_client struct Expanding_region_map_client : Region_map_client
{ {
Genode::Env &_env; Env &_env;
Genode::Pd_connection &_pd; Pd_connection &_pd;
Genode::Ram_quota_guard &_ram_guard; Ram_quota_guard &_ram_guard;
Genode::Cap_quota_guard &_cap_guard; Cap_quota_guard &_cap_guard;
Expanding_region_map_client(Genode::Env &env, Expanding_region_map_client(Env &env,
Genode::Pd_connection &pd, Pd_connection &pd,
Genode::Ram_quota_guard &ram_guard, Ram_quota_guard &ram_guard,
Genode::Cap_quota_guard &cap_guard) Cap_quota_guard &cap_guard)
: :
Region_map_client(pd.address_space()), _env(env), _pd(pd), Region_map_client(pd.address_space()), _env(env), _pd(pd),
_ram_guard(ram_guard), _cap_guard(cap_guard) _ram_guard(ram_guard), _cap_guard(cap_guard)
{ } { }
Local_addr attach(Genode::Dataspace_capability ds, Local_addr attach(Dataspace_capability ds,
Genode::size_t size = 0, Genode::off_t offset = 0, size_t size = 0, off_t offset = 0,
bool use_local_addr = false, bool use_local_addr = false,
Local_addr local_addr = (void *)0, Local_addr local_addr = (void *)0,
bool executable = false, bool executable = false,
bool writeable = true) override bool writeable = true) override
{ {
return Genode::retry<Genode::Out_of_ram>( return retry<Out_of_ram>(
[&] () { [&] () {
return Genode::retry<Genode::Out_of_caps>( return retry<Out_of_caps>(
[&] () { [&] () {
return Region_map_client::attach(ds, size, offset, return Region_map_client::attach(ds, size, offset,
use_local_addr, use_local_addr,
@ -73,7 +76,7 @@ class Platform::Device_pd
writeable); }, writeable); },
[&] () { [&] () {
enum { UPGRADE_CAP_QUOTA = 2 }; enum { UPGRADE_CAP_QUOTA = 2 };
Genode::Cap_quota const caps { UPGRADE_CAP_QUOTA }; Cap_quota const caps { UPGRADE_CAP_QUOTA };
_cap_guard.withdraw(caps); _cap_guard.withdraw(caps);
_env.pd().transfer_quota(_pd.rpc_cap(), caps); _env.pd().transfer_quota(_pd.rpc_cap(), caps);
} }
@ -81,36 +84,38 @@ class Platform::Device_pd
}, },
[&] () { [&] () {
enum { UPGRADE_RAM_QUOTA = 4096 }; enum { UPGRADE_RAM_QUOTA = 4096 };
Genode::Ram_quota const ram { UPGRADE_RAM_QUOTA }; Ram_quota const ram { UPGRADE_RAM_QUOTA };
_ram_guard.withdraw(ram); _ram_guard.withdraw(ram);
_env.pd().transfer_quota(_pd.rpc_cap(), ram); _env.pd().transfer_quota(_pd.rpc_cap(), ram);
} }
); );
} }
Local_addr attach_at(Genode::Dataspace_capability ds, Local_addr attach_at(Dataspace_capability ds,
Genode::addr_t local_addr, addr_t local_addr,
Genode::size_t size = 0, size_t size = 0,
Genode::off_t offset = 0) { off_t offset = 0) {
return attach(ds, size, offset, true, local_addr); }; return attach(ds, size, offset, true, local_addr); };
} _address_space; } _address_space;
public: public:
Device_pd(Genode::Env &env, Device_pd(Env &env,
Genode::Session_label const &label, Session_label const &label,
Genode::Ram_quota_guard &ram_guard, Ram_quota_guard &ram_guard,
Genode::Cap_quota_guard &cap_guard) Cap_quota_guard &cap_guard)
: :
_pd(env, "device PD", Genode::Pd_connection::Virt_space::UNCONSTRAIN), _pd(env, "device PD", Pd_connection::Virt_space::UNCONSTRAIN),
_label(label), _label(label),
_address_space(env, _pd, ram_guard, cap_guard) _address_space(env, _pd, ram_guard, cap_guard)
{ {
_pd.ref_account(env.pd_session_cap()); _pd.ref_account(env.pd_session_cap());
} }
void attach_dma_mem(Genode::Dataspace_capability, Genode::addr_t dma_addr); void attach_dma_mem(Dataspace_capability, addr_t dma_addr);
void assign_pci(Genode::Io_mem_dataspace_capability const, void assign_pci(Io_mem_dataspace_capability const,
Genode::addr_t const, Genode::uint16_t const); addr_t const, uint16_t const);
}; };
#endif /* _DEVICE_PD_H_ */

View File

@ -27,9 +27,6 @@ namespace Platform {
} }
using Genode::size_t;
using Genode::addr_t;
/** /**
* A simple allocator implementation used by the Irq_proxy * A simple allocator implementation used by the Irq_proxy
*/ */
@ -43,8 +40,8 @@ class Platform::Irq_allocator
*/ */
enum { LEGACY = 40, MSI = 64, LEGACY_ARRAY = 64 }; enum { LEGACY = 40, MSI = 64, LEGACY_ARRAY = 64 };
Genode::Bit_array<LEGACY_ARRAY> _legacy { }; Bit_array<LEGACY_ARRAY> _legacy { };
Genode::Bit_allocator<MSI> _msi { }; Bit_allocator<MSI> _msi { };
public: public:
@ -58,7 +55,7 @@ class Platform::Irq_allocator
{ {
try { try {
return _msi.alloc(); return _msi.alloc();
} catch (Genode::Bit_allocator<MSI>::Out_of_indices) { return ~0U; } } catch (Bit_allocator<MSI>::Out_of_indices) { return ~0U; }
} }
void free_msi(unsigned msi) { _msi.free(msi); } void free_msi(unsigned msi) { _msi.free(msi); }
@ -89,8 +86,8 @@ class Platform::Irq_component : public Platform::Irq_proxy
{ {
private: private:
Genode::Irq_connection _irq; Irq_connection _irq;
Genode::Signal_handler<Platform::Irq_component> _irq_dispatcher; Signal_handler<Platform::Irq_component> _irq_dispatcher;
bool _associated; bool _associated;
@ -117,15 +114,15 @@ class Platform::Irq_component : public Platform::Irq_proxy
/* De-associate handler. */ /* De-associate handler. */
_associated = false; _associated = false;
_irq.sigh(Genode::Signal_context_capability()); _irq.sigh(Signal_context_capability());
return true; return true;
} }
public: public:
Irq_component(Genode::Env &env, unsigned gsi, Irq_component(Env &env, unsigned gsi,
Genode::Irq_session::Trigger trigger, Irq_session::Trigger trigger,
Genode::Irq_session::Polarity polarity) Irq_session::Polarity polarity)
: :
Irq_proxy(gsi), Irq_proxy(gsi),
_irq(env, gsi, trigger, polarity), _irq(env, gsi, trigger, polarity),
@ -135,15 +132,15 @@ class Platform::Irq_component : public Platform::Irq_proxy
static Irq_component *get_irq_proxy(unsigned irq_number, static Irq_component *get_irq_proxy(unsigned irq_number,
Irq_allocator *irq_alloc = nullptr, Irq_allocator *irq_alloc = nullptr,
Genode::Irq_session::Trigger trigger = Genode::Irq_session::TRIGGER_UNCHANGED, Irq_session::Trigger trigger = Irq_session::TRIGGER_UNCHANGED,
Genode::Irq_session::Polarity polarity = Genode::Irq_session::POLARITY_UNCHANGED, Irq_session::Polarity polarity = Irq_session::POLARITY_UNCHANGED,
Genode::Env *env = nullptr, Env *env = nullptr,
Genode::Allocator *heap = nullptr) Allocator *heap = nullptr)
{ {
static Genode::List<Irq_proxy> proxies; static List<Irq_proxy> proxies;
static Genode::Mutex proxies_mutex; static Mutex proxies_mutex;
Genode::Mutex::Guard mutex_guard(proxies_mutex); Mutex::Guard mutex_guard(proxies_mutex);
/* lookup proxy in database */ /* lookup proxy in database */
for (Irq_proxy *p = proxies.first(); p; p = p->next()) for (Irq_proxy *p = proxies.first(); p; p = p->next())
@ -177,7 +174,7 @@ void Platform::Irq_session_component::ack_irq()
/* shared irq handling */ /* shared irq handling */
Irq_component *irq_obj = Irq_component::get_irq_proxy(_gsi); Irq_component *irq_obj = Irq_component::get_irq_proxy(_gsi);
if (!irq_obj) { if (!irq_obj) {
Genode::error("expected to find IRQ proxy for IRQ ", Genode::Hex(_gsi)); error("expected to find IRQ proxy for IRQ ", Hex(_gsi));
return; return;
} }
@ -186,10 +183,10 @@ void Platform::Irq_session_component::ack_irq()
} }
Platform::Irq_session_component::Irq_session_component(unsigned irq, Platform::Irq_session_component::Irq_session_component(unsigned irq,
addr_t pci_config_space, addr_t pci_config_space,
Genode::Env &env, Env &env,
Genode::Allocator &heap) Allocator &heap)
: :
_gsi(irq) _gsi(irq)
{ {
@ -209,7 +206,7 @@ Platform::Irq_session_component::Irq_session_component(unsigned irq,
_gsi = msi; _gsi = msi;
return; return;
} }
} catch (Genode::Service_denied) { } } catch (Service_denied) { }
irq_alloc.free_msi(msi); irq_alloc.free_msi(msi);
} }
@ -219,15 +216,15 @@ Platform::Irq_session_component::Irq_session_component(unsigned irq,
if (_gsi >= INVALID_IRQ) if (_gsi >= INVALID_IRQ)
return; return;
Genode::Irq_session::Trigger trigger; Irq_session::Trigger trigger;
Genode::Irq_session::Polarity polarity; Irq_session::Polarity polarity;
_gsi = Platform::Irq_override::irq_override(_gsi, trigger, polarity); _gsi = Platform::Irq_override::irq_override(_gsi, trigger, polarity);
if (_gsi != irq || trigger != Genode::Irq_session::TRIGGER_UNCHANGED || if (_gsi != irq || trigger != Irq_session::TRIGGER_UNCHANGED ||
polarity != POLARITY_UNCHANGED) { polarity != POLARITY_UNCHANGED) {
Genode::log("IRQ override ", irq, "->", _gsi, ", " log("IRQ override ", irq, "->", _gsi, ", "
"trigger mode: ", trigger, ", ", "polarity: ", polarity); "trigger mode: ", trigger, ", ", "polarity: ", polarity);
} }
try { try {
@ -235,16 +232,16 @@ Platform::Irq_session_component::Irq_session_component(unsigned irq,
if (Irq_component::get_irq_proxy(_gsi, &irq_alloc, trigger, if (Irq_component::get_irq_proxy(_gsi, &irq_alloc, trigger,
polarity, &env, &heap)) polarity, &env, &heap))
return; return;
} catch (Genode::Service_denied) { } } catch (Service_denied) { }
Genode::error("unavailable IRQ ", Genode::Hex(_gsi), " requested"); error("unavailable IRQ ", Hex(_gsi), " requested");
} }
Platform::Irq_session_component::~Irq_session_component() Platform::Irq_session_component::~Irq_session_component()
{ {
if (msi()) { if (msi()) {
_irq_conn->sigh(Genode::Signal_context_capability()); _irq_conn->sigh(Signal_context_capability());
irq_alloc.free_msi(_gsi); irq_alloc.free_msi(_gsi);
return; return;
@ -259,7 +256,7 @@ Platform::Irq_session_component::~Irq_session_component()
} }
void Platform::Irq_session_component::sigh(Genode::Signal_context_capability sigh) void Platform::Irq_session_component::sigh(Signal_context_capability sigh)
{ {
if (_irq_conn.constructed()) { if (_irq_conn.constructed()) {
/* register signal handler for msi directly at parent */ /* register signal handler for msi directly at parent */
@ -270,11 +267,11 @@ void Platform::Irq_session_component::sigh(Genode::Signal_context_capability sig
/* shared irq handling */ /* shared irq handling */
Irq_component *irq_obj = Irq_component::get_irq_proxy(_gsi); Irq_component *irq_obj = Irq_component::get_irq_proxy(_gsi);
if (!irq_obj) { if (!irq_obj) {
Genode::error("signal handler got not registered - irq object unavailable"); error("signal handler got not registered - irq object unavailable");
return; return;
} }
Genode::Signal_context_capability old = _irq_sigh; Signal_context_capability old = _irq_sigh;
if (old.valid() && !sigh.valid()) if (old.valid() && !sigh.valid())
irq_obj->remove_sharer(&_irq_sigh); irq_obj->remove_sharer(&_irq_sigh);

View File

@ -31,31 +31,30 @@ namespace Platform {
} }
class Platform::Irq_session_component : public Genode::Rpc_object<Genode::Irq_session>, class Platform::Irq_session_component : public Rpc_object<Irq_session>,
private Genode::List<Irq_session_component>::Element private List<Irq_session_component>::Element
{ {
private: private:
friend class Genode::List<Irq_session_component>; friend class List<Irq_session_component>;
unsigned _gsi; unsigned _gsi;
Platform::Irq_sigh _irq_sigh { }; Platform::Irq_sigh _irq_sigh { };
Genode::Irq_session::Info _msi_info { }; Irq_session::Info _msi_info { };
Genode::Constructible<Genode::Irq_connection> _irq_conn { }; Constructible<Irq_connection> _irq_conn { };
public: public:
enum { INVALID_IRQ = 0xffU }; enum { INVALID_IRQ = 0xffU };
Irq_session_component(unsigned, Genode::addr_t, Genode::Env &, Irq_session_component(unsigned, addr_t, Env &, Allocator &heap);
Genode::Allocator &heap);
~Irq_session_component(); ~Irq_session_component();
bool msi() bool msi()
{ {
return _irq_conn.constructed() && return _irq_conn.constructed() &&
_msi_info.type == Genode::Irq_session::Info::Type::MSI; _msi_info.type == Irq_session::Info::Type::MSI;
} }
unsigned gsi() { return _gsi; } unsigned gsi() { return _gsi; }
@ -68,7 +67,7 @@ class Platform::Irq_session_component : public Genode::Rpc_object<Genode::Irq_s
***************************/ ***************************/
void ack_irq() override; void ack_irq() override;
void sigh(Genode::Signal_context_capability) override; void sigh(Signal_context_capability) override;
Info info() override Info info() override
{ {
@ -80,41 +79,41 @@ class Platform::Irq_session_component : public Genode::Rpc_object<Genode::Irq_s
/** /**
* List that holds interrupt override information * List that holds interrupt override information
*/ */
class Platform::Irq_override : public Genode::List<Platform::Irq_override>::Element class Platform::Irq_override : public List<Platform::Irq_override>::Element
{ {
private: private:
unsigned short _irq; /* source IRQ */ unsigned short const _irq; /* source IRQ */
unsigned short _gsi; /* target GSI */ unsigned short const _gsi; /* target GSI */
Genode::Irq_session::Trigger _trigger; /* interrupt trigger mode */ Irq_session::Trigger const _trigger; /* interrupt trigger mode */
Genode::Irq_session::Polarity _polarity; /* interrupt polarity */ Irq_session::Polarity const _polarity; /* interrupt polarity */
Genode::Irq_session::Trigger _mode2trigger(unsigned mode) Irq_session::Trigger _mode2trigger(unsigned mode)
{ {
enum { EDGE = 0x4, LEVEL = 0xc }; enum { EDGE = 0x4, LEVEL = 0xc };
switch (mode & 0xc) { switch (mode & 0xc) {
case EDGE: case EDGE:
return Genode::Irq_session::TRIGGER_EDGE; return Irq_session::TRIGGER_EDGE;
case LEVEL: case LEVEL:
return Genode::Irq_session::TRIGGER_LEVEL; return Irq_session::TRIGGER_LEVEL;
default: default:
return Genode::Irq_session::TRIGGER_UNCHANGED; return Irq_session::TRIGGER_UNCHANGED;
} }
} }
Genode::Irq_session::Polarity _mode2polarity(unsigned mode) Irq_session::Polarity _mode2polarity(unsigned mode)
{ {
using namespace Genode; using namespace Genode;
enum { HIGH = 0x1, LOW = 0x3 }; enum { HIGH = 0x1, LOW = 0x3 };
switch (mode & 0x3) { switch (mode & 0x3) {
case HIGH: case HIGH:
return Genode::Irq_session::POLARITY_HIGH; return Irq_session::POLARITY_HIGH;
case LOW: case LOW:
return Genode::Irq_session::POLARITY_LOW; return Irq_session::POLARITY_LOW;
default: default:
return Genode::Irq_session::POLARITY_UNCHANGED; return Irq_session::POLARITY_UNCHANGED;
} }
} }
@ -122,24 +121,24 @@ class Platform::Irq_override : public Genode::List<Platform::Irq_override>::Elem
Irq_override(unsigned irq, unsigned gsi, unsigned mode) Irq_override(unsigned irq, unsigned gsi, unsigned mode)
: :
_irq(irq), _gsi(gsi), _irq(irq), _gsi(gsi),
_trigger(_mode2trigger(mode)), _polarity(_mode2polarity(mode)) _trigger(_mode2trigger(mode)), _polarity(_mode2polarity(mode))
{ } { }
static Genode::List<Irq_override> *list() static List<Irq_override> *list()
{ {
static Genode::List<Irq_override> _list; static List<Irq_override> _list;
return &_list; return &_list;
} }
unsigned short irq() const { return _irq; } unsigned short irq() const { return _irq; }
unsigned short gsi() const { return _gsi; } unsigned short gsi() const { return _gsi; }
Genode::Irq_session::Trigger trigger() const { return _trigger; } Irq_session::Trigger trigger() const { return _trigger; }
Genode::Irq_session::Polarity polarity() const { return _polarity; } Irq_session::Polarity polarity() const { return _polarity; }
static unsigned irq_override (unsigned irq, static unsigned irq_override (unsigned irq,
Genode::Irq_session::Trigger &trigger, Irq_session::Trigger &trigger,
Genode::Irq_session::Polarity &polarity) Irq_session::Polarity &polarity)
{ {
for (Irq_override *i = list()->first(); i; i = i->next()) for (Irq_override *i = list()->first(); i; i = i->next())
if (i->irq() == irq) { if (i->irq() == irq) {
@ -148,8 +147,8 @@ class Platform::Irq_override : public Genode::List<Platform::Irq_override>::Elem
return i->gsi(); return i->gsi();
} }
trigger = Genode::Irq_session::TRIGGER_UNCHANGED; trigger = Irq_session::TRIGGER_UNCHANGED;
polarity = Genode::Irq_session::POLARITY_UNCHANGED; polarity = Irq_session::POLARITY_UNCHANGED;
return irq; return irq;
} }
}; };
@ -158,7 +157,7 @@ class Platform::Irq_override : public Genode::List<Platform::Irq_override>::Elem
/** /**
* List that holds interrupt rewrite information * List that holds interrupt rewrite information
*/ */
class Platform::Irq_routing : public Genode::List<Platform::Irq_routing>::Element class Platform::Irq_routing : public List<Platform::Irq_routing>::Element
{ {
private: private:
@ -169,9 +168,9 @@ class Platform::Irq_routing : public Genode::List<Platform::Irq_routing>::Elemen
public: public:
static Genode::List<Irq_routing> *list() static List<Irq_routing> *list()
{ {
static Genode::List<Irq_routing> _list; static List<Irq_routing> _list;
return &_list; return &_list;
} }

View File

@ -23,20 +23,20 @@ namespace Platform {
} }
class Platform::Irq_sigh : public Genode::Signal_context_capability, class Platform::Irq_sigh : public Signal_context_capability,
public Genode::List<Platform::Irq_sigh>::Element public List<Platform::Irq_sigh>::Element
{ {
public: public:
Irq_sigh & operator= (const Genode::Signal_context_capability &cap) Irq_sigh & operator= (Signal_context_capability const &cap)
{ {
Genode::Signal_context_capability::operator=(cap); Signal_context_capability::operator=(cap);
return *this; return *this;
} }
Irq_sigh() { } Irq_sigh() { }
void notify() { Genode::Signal_transmitter(*this).submit(1); } void notify() { Signal_transmitter(*this).submit(1); }
}; };
@ -46,33 +46,29 @@ class Platform::Irq_sigh : public Genode::Signal_context_capability,
* *
* XXX resources are not accounted as the interrupt is shared * XXX resources are not accounted as the interrupt is shared
*/ */
class Platform::Irq_proxy : private Genode::List<Platform::Irq_proxy>::Element class Platform::Irq_proxy : private List<Platform::Irq_proxy>::Element
{ {
private: private:
friend class Genode::List<Platform::Irq_proxy>; friend class List<Platform::Irq_proxy>;
protected: protected:
unsigned _irq_number; unsigned const _irq_number;
Genode::Mutex _mutex { }; /* protects this object */
int _num_sharers; /* number of clients sharing this IRQ */
Genode::List<Irq_sigh> _sigh_list { }; List<Irq_sigh> _sigh_list { };
int _num_acknowledgers; /* number of currently blocked clients */ Mutex _mutex { }; /* protects this object */
bool _woken_up; /* client decided to wake me up - int _num_sharers = 0; /* number of clients sharing this IRQ */
this prevents multiple wakeups int _num_acknowledgers = 0; /* number of currently blocked clients */
to happen during initialization */ bool _woken_up = false; /* client decided to wake me up -
this prevents multiple wakeups
to happen during initialization */
public: public:
using Genode::List<Platform::Irq_proxy>::Element::next; using List<Platform::Irq_proxy>::Element::next;
Irq_proxy(unsigned irq_number) Irq_proxy(unsigned irq_number) : _irq_number(irq_number) { }
:
_irq_number(irq_number), _num_sharers(0),
_num_acknowledgers(0), _woken_up(false)
{ }
virtual ~Irq_proxy() { } virtual ~Irq_proxy() { }
@ -81,7 +77,7 @@ class Platform::Irq_proxy : private Genode::List<Platform::Irq_proxy>::Element
*/ */
virtual bool ack_irq() virtual bool ack_irq()
{ {
Genode::Mutex::Guard mutex_guard(_mutex); Mutex::Guard mutex_guard(_mutex);
_num_acknowledgers++; _num_acknowledgers++;
@ -101,7 +97,7 @@ class Platform::Irq_proxy : private Genode::List<Platform::Irq_proxy>::Element
*/ */
void notify_about_irq() void notify_about_irq()
{ {
Genode::Mutex::Guard mutex_guard(_mutex); Mutex::Guard mutex_guard(_mutex);
/* reset acknowledger state */ /* reset acknowledger state */
_num_acknowledgers = 0; _num_acknowledgers = 0;
@ -116,7 +112,7 @@ class Platform::Irq_proxy : private Genode::List<Platform::Irq_proxy>::Element
virtual bool add_sharer(Irq_sigh *s) virtual bool add_sharer(Irq_sigh *s)
{ {
Genode::Mutex::Guard mutex_guard(_mutex); Mutex::Guard mutex_guard(_mutex);
++_num_sharers; ++_num_sharers;
_sigh_list.insert(s); _sigh_list.insert(s);
@ -126,7 +122,7 @@ class Platform::Irq_proxy : private Genode::List<Platform::Irq_proxy>::Element
virtual bool remove_sharer(Irq_sigh *s) virtual bool remove_sharer(Irq_sigh *s)
{ {
Genode::Mutex::Guard mutex_guard(_mutex); Mutex::Guard mutex_guard(_mutex);
_sigh_list.remove(s); _sigh_list.remove(s);
--_num_sharers; --_num_sharers;

View File

@ -21,9 +21,8 @@
#include "pci_device_config.h" #include "pci_device_config.h"
#include "device_pd.h" #include "device_pd.h"
namespace Platform { namespace Platform { struct Main; };
struct Main;
};
struct Platform::Main struct Platform::Main
{ {
@ -31,16 +30,16 @@ struct Platform::Main
* Use sliced heap to allocate each session component at a separate * Use sliced heap to allocate each session component at a separate
* dataspace. * dataspace.
*/ */
Genode::Env &_env; Env &_env;
Genode::Sliced_heap sliced_heap { _env.ram(), _env.rm() }; Sliced_heap sliced_heap { _env.ram(), _env.rm() };
Genode::Attached_rom_dataspace _config { _env, "config" }; Attached_rom_dataspace _config { _env, "config" };
Genode::Constructible<Genode::Attached_rom_dataspace> acpi_rom { }; Constructible<Attached_rom_dataspace> acpi_rom { };
Genode::Constructible<Platform::Root> root { }; Constructible<Platform::Root> root { };
Genode::Constructible<Genode::Attached_rom_dataspace> system_state { }; Constructible<Attached_rom_dataspace> system_state { };
Genode::Constructible<Genode::Attached_rom_dataspace> acpi_ready { }; Constructible<Attached_rom_dataspace> acpi_ready { };
Signal_handler<Main> _acpi_report { _env.ep(), *this, Signal_handler<Main> _acpi_report { _env.ep(), *this,
&Main::acpi_update }; &Main::acpi_update };
@ -49,7 +48,7 @@ struct Platform::Main
Signal_handler<Main> _config_handler { _env.ep(), *this, Signal_handler<Main> _config_handler { _env.ep(), *this,
&Main::config_update }; &Main::config_update };
Genode::Capability<Genode::Typed_root<Platform::Session_component> > root_cap { }; Capability<Typed_root<Platform::Session_component> > root_cap { };
bool const _acpi_platform; bool const _acpi_platform;
bool _acpi_ready = false; bool _acpi_ready = false;
@ -78,7 +77,7 @@ struct Platform::Main
root_cap = _env.ep().manage(*root); root_cap = _env.ep().manage(*root);
if (_acpi_ready) { if (_acpi_ready) {
Genode::Parent::Service_name announce_for_acpi("Acpi"); Parent::Service_name announce_for_acpi("Acpi");
_env.parent().announce(announce_for_acpi, root_cap); _env.parent().announce(announce_for_acpi, root_cap);
} else } else
_env.parent().announce(root_cap); _env.parent().announce(root_cap);
@ -93,15 +92,14 @@ struct Platform::Main
return; return;
if (acpi_ready.constructed() && acpi_ready->valid()) { if (acpi_ready.constructed() && acpi_ready->valid()) {
Genode::Xml_node system(acpi_ready->local_addr<char>(), Xml_node system(acpi_ready->local_addr<char>(), acpi_ready->size());
acpi_ready->size());
typedef Genode::String<16> Value; typedef String<16> Value;
const Value state = system.attribute_value("state", Value("unknown")); const Value state = system.attribute_value("state", Value("unknown"));
if (state == "acpi_ready" && root_cap.valid()) { if (state == "acpi_ready" && root_cap.valid()) {
_env.parent().announce(root_cap); _env.parent().announce(root_cap);
root_cap = Genode::Capability<Genode::Typed_root<Platform::Session_component> > (); root_cap = Capability<Typed_root<Platform::Session_component> > ();
} }
} }
} }
@ -136,11 +134,11 @@ struct Platform::Main
} }
} }
static bool acpi_platform(Genode::Env & env) static bool acpi_platform(Env & env)
{ {
using Name = String<32>; using Name = String<32>;
try { try {
Genode::Attached_rom_dataspace info { env, "platform_info" }; Attached_rom_dataspace info { env, "platform_info" };
Name kernel = Name kernel =
info.xml().sub_node("kernel").attribute_value("name", Name()); info.xml().sub_node("kernel").attribute_value("name", Name());
if (kernel == "hw" || if (kernel == "hw" ||
@ -151,7 +149,7 @@ struct Platform::Main
return false; return false;
} }
Main(Genode::Env &env) Main(Env &env)
: :
_env(env), _env(env),
_acpi_platform(acpi_platform(env)) _acpi_platform(acpi_platform(env))
@ -180,8 +178,6 @@ struct Platform::Main
void Platform::Main::_attempt_acpi_reset() void Platform::Main::_attempt_acpi_reset()
{ {
using namespace Genode;
if (!acpi_rom.constructed()) if (!acpi_rom.constructed())
return; return;

View File

@ -1,10 +1,11 @@
/* /*
* \brief Non PCI devices, e.g. PS2 * \brief Non PCI devices, e.g. PS2
* \author Alexander Boettcher * \author Alexander Boettcher
* \date 2015-04-17
*/ */
/* /*
* Copyright (C) 2015-2017 Genode Labs GmbH * Copyright (C) 2015-2021 Genode Labs GmbH
* *
* This file is part of the Genode OS framework, which is distributed * This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3. * under the terms of the GNU Affero General Public License version 3.
@ -13,10 +14,10 @@
#include "pci_session_component.h" #include "pci_session_component.h"
#include "irq.h" #include "irq.h"
namespace Platform { namespace Nonpci { class Ps2; class Pit; } }
namespace Nonpci { class Ps2; class Pit; }
class Nonpci::Ps2 : public Platform::Device_component class Platform::Nonpci::Ps2 : public Device_component
{ {
private: private:
@ -29,22 +30,22 @@ class Nonpci::Ps2 : public Platform::Device_component
REG_STATUS = 0x64, REG_STATUS = 0x64,
}; };
Genode::Rpc_entrypoint &_ep; Rpc_entrypoint &_ep;
Platform::Irq_session_component _irq_mouse; Platform::Irq_session_component _irq_mouse;
Genode::Io_port_connection _data; Io_port_connection _data;
Genode::Io_port_connection _status; Io_port_connection _status;
public: public:
Ps2(Genode::Env &env, Ps2(Env &env,
Genode::Attached_io_mem_dataspace &pciconf, Attached_io_mem_dataspace &pciconf,
Platform::Session_component &session, Session_component &session,
Genode::Allocator &heap_for_irq, Allocator &heap_for_irq,
Platform::Pci::Config::Delayer &delayer, Pci::Config::Delayer &delayer,
Platform::Device_bars_pool &devices_bars) Device_bars_pool &devices_bars)
: :
Platform::Device_component(env, pciconf, session, IRQ_KEYBOARD, Device_component(env, pciconf, session, IRQ_KEYBOARD,
heap_for_irq, delayer, devices_bars), heap_for_irq, delayer, devices_bars),
_ep(env.ep().rpc_ep()), _ep(env.ep().rpc_ep()),
_irq_mouse(IRQ_MOUSE, ~0UL, env, heap_for_irq), _irq_mouse(IRQ_MOUSE, ~0UL, env, heap_for_irq),
_data(env, REG_DATA, ACCESS_WIDTH), _data(env, REG_DATA, ACCESS_WIDTH),
@ -55,43 +56,40 @@ class Nonpci::Ps2 : public Platform::Device_component
~Ps2() { _ep.dissolve(&_irq_mouse); } ~Ps2() { _ep.dissolve(&_irq_mouse); }
Genode::Irq_session_capability irq(Genode::uint8_t virt_irq) override Irq_session_capability irq(uint8_t virt_irq) override
{ {
switch (virt_irq) { switch (virt_irq) {
case 0: case 0:
Genode::log("PS2 uses IRQ, vector ", Genode::Hex(IRQ_KEYBOARD)); log("PS2 uses IRQ, vector ", Hex(IRQ_KEYBOARD));
return Device_component::irq(virt_irq); return Device_component::irq(virt_irq);
case 1: case 1:
Genode::log("PS2 uses IRQ, vector ", Genode::Hex(IRQ_MOUSE)); log("PS2 uses IRQ, vector ", Hex(IRQ_MOUSE));
return _irq_mouse.cap(); return _irq_mouse.cap();
default: default:
return Genode::Irq_session_capability(); return Irq_session_capability();
} }
} }
Genode::Io_port_session_capability io_port(Genode::uint8_t io_port) override Io_port_session_capability io_port(uint8_t io_port) override
{ {
if (io_port == 0) if (io_port == 0)
return _data.cap(); return _data.cap();
if (io_port == 1) if (io_port == 1)
return _status.cap(); return _status.cap();
return Genode::Io_port_session_capability(); return Io_port_session_capability();
} }
Genode::Io_mem_session_capability io_mem(Genode::uint8_t, Io_mem_session_capability io_mem(uint8_t, Cache, addr_t, size_t) override
Genode::Cache,
Genode::addr_t,
Genode::size_t) override
{ {
return Genode::Io_mem_session_capability(); return Io_mem_session_capability();
} }
virtual String<5> name() const override { return "PS2"; } String<5> name() const override { return "PS2"; }
}; };
class Nonpci::Pit : public Platform::Device_component class Platform::Nonpci::Pit : public Device_component
{ {
private: private:
@ -102,44 +100,42 @@ class Nonpci::Pit : public Platform::Device_component
PORTS_WIDTH = 4 PORTS_WIDTH = 4
}; };
Genode::Io_port_connection _ports; Io_port_connection _ports;
public: public:
Pit(Genode::Env &env, Pit(Env &env,
Genode::Attached_io_mem_dataspace &pciconf, Attached_io_mem_dataspace &pciconf,
Platform::Session_component &session, Session_component &session,
Genode::Allocator &heap_for_irq, Allocator &heap_for_irq,
Platform::Pci::Config::Delayer &delayer, Pci::Config::Delayer &delayer,
Platform::Device_bars_pool &devices_bars) Device_bars_pool &devices_bars)
: :
Platform::Device_component(env, pciconf, session, IRQ_PIT, Device_component(env, pciconf, session, IRQ_PIT,
heap_for_irq, delayer, devices_bars), heap_for_irq, delayer, devices_bars),
_ports(env, PIT_PORT, PORTS_WIDTH) _ports(env, PIT_PORT, PORTS_WIDTH)
{ } { }
Genode::Io_port_session_capability io_port(Genode::uint8_t io_port) override Io_port_session_capability io_port(uint8_t io_port) override
{ {
if (io_port == 0) if (io_port == 0)
return _ports.cap(); return _ports.cap();
return Genode::Io_port_session_capability(); return Io_port_session_capability();
} }
virtual String<5> name() const override { return "PIT"; } String<5> name() const override { return "PIT"; }
}; };
/** /**
* Platform session component devices which are non PCI devices, e.g. PS2 * Platform session component devices which are non PCI devices, e.g. PS2
*/ */
Platform::Device_capability Platform::Session_component::device(String const &name) { Platform::Device_capability Platform::Session_component::device(Device_name const &name)
{
if (!name.valid_string()) if (!name.valid_string())
return Device_capability(); return Device_capability();
using namespace Genode;
char const * device_name = name.string(); char const * device_name = name.string();
const char * devices [] = { "PS2", "PIT" }; const char * devices [] = { "PS2", "PIT" };
unsigned devices_i = 0; unsigned devices_i = 0;
@ -149,13 +145,13 @@ Platform::Device_capability Platform::Session_component::device(String const &na
break; break;
if (devices_i >= sizeof(devices) / sizeof(devices[0])) { if (devices_i >= sizeof(devices) / sizeof(devices[0])) {
Genode::error("unknown '", device_name, " device name"); error("unknown '", device_name, " device name");
return Device_capability(); return Device_capability();
} }
if (!permit_device(devices[devices_i])) { if (!permit_device(devices[devices_i])) {
Genode::error("denied access to device '", device_name, "' for " error("denied access to device '", device_name, "' for "
"session '", _label, "'"); "session '", _label, "'");
return Device_capability(); return Device_capability();
} }
@ -180,6 +176,6 @@ Platform::Device_capability Platform::Session_component::device(String const &na
_device_list.insert(dev); _device_list.insert(dev);
return _env.ep().rpc_ep().manage(dev); return _env.ep().rpc_ep().manage(dev);
} }
catch (Genode::Out_of_ram) { throw; } catch (Out_of_ram) { throw; }
catch (Genode::Service_denied) { return Device_capability(); } catch (Service_denied) { return Device_capability(); }
} }

View File

@ -11,17 +11,18 @@
* under the terms of the GNU Affero General Public License version 3. * under the terms of the GNU Affero General Public License version 3.
*/ */
#pragma once #ifndef _PCI_BRIDGE_H_
#define _PCI_BRIDGE_H_
namespace Platform { class Bridge; }
#include <util/list.h> #include <util/list.h>
namespace Platform { class Bridge; }
/** /**
* List of PCI-bridge devices * List of PCI-bridge devices
*/ */
class Platform::Bridge : public Genode::List<Bridge>::Element class Platform::Bridge : public List<Bridge>::Element
{ {
private: private:
@ -57,3 +58,5 @@ class Platform::Bridge : public Genode::List<Bridge>::Element
enum { INVALID_ROOT_BRIDGE = 0x10000U }; enum { INVALID_ROOT_BRIDGE = 0x10000U };
static unsigned root_bridge_bdf; static unsigned root_bridge_bdf;
}; };
#endif /* _PCI_BRIDGE_H_ */

View File

@ -1,12 +1,11 @@
/* /*
* \brief Interface for accessing PCI configuration registers * \brief PCI configuration access for the platform driver
* \author Norman Feske * \author Norman Feske
* \author Reto Buerki * \date 2008-01-28
* \date 2008-01-29
*/ */
/* /*
* Copyright (C) 2008-2017 Genode Labs GmbH * Copyright (C) 2008-2021 Genode Labs GmbH
* *
* This file is part of the Genode OS framework, which is distributed * This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3. * under the terms of the GNU Affero General Public License version 3.
@ -21,8 +20,6 @@
#include <util/bit_array.h> #include <util/bit_array.h>
#include <util/mmio.h> #include <util/mmio.h>
using namespace Genode;
namespace Platform { namespace Pci { struct Bdf; struct Config; } } namespace Platform { namespace Pci { struct Bdf; struct Config; } }
@ -43,10 +40,9 @@ struct Platform::Pci::Bdf
bool operator == (Bdf const &other) const { bool operator == (Bdf const &other) const {
return value() == other.value(); } return value() == other.value(); }
void print(Genode::Output &out) const void print(Output &out) const
{ {
using Genode::print; using Genode::print;
using Genode::Hex;
print(out, Hex(bus, Hex::Prefix::OMIT_PREFIX, Hex::Pad::PAD), print(out, Hex(bus, Hex::Prefix::OMIT_PREFIX, Hex::Pad::PAD),
":", Hex(device, Hex::Prefix::OMIT_PREFIX, Hex::Pad::PAD), ":", Hex(device, Hex::Prefix::OMIT_PREFIX, Hex::Pad::PAD),
".", Hex(function, Hex::Prefix::OMIT_PREFIX)); ".", Hex(function, Hex::Prefix::OMIT_PREFIX));
@ -61,7 +57,8 @@ namespace Platform {
private: private:
Attached_io_mem_dataspace &_pciconf; Attached_io_mem_dataspace &_pciconf;
Genode::size_t const _pciconf_size;
size_t const _pciconf_size;
/** /**
* Calculate device offset from BDF * Calculate device offset from BDF
@ -73,7 +70,7 @@ namespace Platform {
return unsigned(bdf.value()) << 12; return unsigned(bdf.value()) << 12;
} }
Genode::Bit_array<256> _used { }; Bit_array<256> _used { };
void _use_register(unsigned char addr, unsigned short width) void _use_register(unsigned char addr, unsigned short width)
{ {
@ -84,7 +81,7 @@ namespace Platform {
public: public:
class Invalid_mmio_access : Genode::Exception { }; class Invalid_mmio_access : Exception { };
Config_access(Attached_io_mem_dataspace &pciconf) Config_access(Attached_io_mem_dataspace &pciconf)
: :

View File

@ -13,10 +13,11 @@
#include "pci_session_component.h" #include "pci_session_component.h"
#include "pci_device_component.h" #include "pci_device_component.h"
Genode::Io_port_session_capability Platform::Device_component::io_port(Genode::uint8_t const v_id)
Genode::Io_port_session_capability Platform::Device_component::io_port(uint8_t const v_id)
{ {
Genode::uint8_t const max = sizeof(_io_port_conn) / sizeof(_io_port_conn[0]); uint8_t const max = sizeof(_io_port_conn) / sizeof(_io_port_conn[0]);
Genode::uint8_t r_id = 0; uint8_t r_id = 0;
for (unsigned i = 0; i < max; ++i) { for (unsigned i = 0; i < max; ++i) {
Pci::Resource res = _device_config.resource(i); Pci::Resource res = _device_config.resource(i);
@ -33,23 +34,24 @@ Genode::Io_port_session_capability Platform::Device_component::io_port(Genode::u
return _io_port_conn[v_id]->cap(); return _io_port_conn[v_id]->cap();
try { try {
_io_port_conn[v_id] = new (_slab_ioport) Genode::Io_port_connection(_env, res.base(), res.size()); _io_port_conn[v_id] = new (_slab_ioport)
Io_port_connection(_env, res.base(), res.size());
return _io_port_conn[v_id]->cap(); return _io_port_conn[v_id]->cap();
} catch (...) { } catch (...) {
return Genode::Io_port_session_capability(); return Io_port_session_capability();
} }
} }
return Genode::Io_port_session_capability(); return Io_port_session_capability();
} }
Genode::Io_mem_session_capability Platform::Device_component::io_mem(Genode::uint8_t const v_id, Genode::Io_mem_session_capability Platform::Device_component::io_mem(uint8_t const v_id,
Genode::Cache const caching, Cache const caching,
Genode::addr_t const offset, addr_t const offset,
Genode::size_t const size) size_t const size)
{ {
Genode::uint8_t max = sizeof(_io_mem) / sizeof(_io_mem[0]); uint8_t max = sizeof(_io_mem) / sizeof(_io_mem[0]);
Genode::uint8_t r_id = 0; uint8_t r_id = 0;
for (unsigned i = 0; i < max; ++i) { for (unsigned i = 0; i < max; ++i) {
Pci::Resource res = _device_config.resource(i); Pci::Resource res = _device_config.resource(i);
@ -63,42 +65,41 @@ Genode::Io_mem_session_capability Platform::Device_component::io_mem(Genode::uin
} }
/* limit IO_MEM session size to resource size */ /* limit IO_MEM session size to resource size */
Genode::size_t const res_size = Genode::min(size, res.size()); size_t const res_size = min(size, res.size());
if (offset >= res.size() || offset > res.size() - res_size) if (offset >= res.size() || offset > res.size() - res_size)
return Genode::Io_mem_session_capability(); return Io_mem_session_capability();
/* error if MEM64 resource base address above 4G on 32-bit */ /* error if MEM64 resource base address above 4G on 32-bit */
if (res.base() > ~(addr_t)0) { if (res.base() > ~(addr_t)0) {
Genode::error("request for MEM64 resource of ", _device_config, error("request for MEM64 resource of ", _device_config,
" at ", Genode::Hex(res.base()), " at ", Hex(res.base()), " not supported on 32-bit system");
" not supported on 32-bit system"); return Io_mem_session_capability();
return Genode::Io_mem_session_capability();
} }
try { try {
bool const wc = caching == Genode::Cache::WRITE_COMBINED; bool const wc = caching == Cache::WRITE_COMBINED;
Io_mem * io_mem = new (_slab_iomem) Io_mem(_env, Io_mem * io_mem = new (_slab_iomem) Io_mem(_env,
res.base() + offset, res.base() + offset,
res_size, wc); res_size, wc);
_io_mem[i].insert(io_mem); _io_mem[i].insert(io_mem);
return io_mem->cap(); return io_mem->cap();
} }
catch (Genode::Out_of_caps) { catch (Out_of_caps) {
Genode::warning("Out_of_caps in Device_component::io_mem"); warning("Out_of_caps in Device_component::io_mem");
throw; throw;
} }
catch (Genode::Out_of_ram) { catch (Out_of_ram) {
Genode::warning("Out_of_ram in Device_component::io_mem"); warning("Out_of_ram in Device_component::io_mem");
throw; throw;
} }
catch (...) { catch (...) {
Genode::warning("unhandled exception in 'Device_component::io_mem'"); warning("unhandled exception in 'Device_component::io_mem'");
return Genode::Io_mem_session_capability(); return Io_mem_session_capability();
} }
} }
return Genode::Io_mem_session_capability(); return Io_mem_session_capability();
} }
void Platform::Device_component::config_write(unsigned char address, void Platform::Device_component::config_write(unsigned char address,
@ -112,11 +113,11 @@ void Platform::Device_component::config_write(unsigned char address,
if (!_device_config.reg_in_use(_config_access, address, size)) if (!_device_config.reg_in_use(_config_access, address, size))
break; break;
Genode::error(_device_config, " write access to " error(_device_config, " write access to "
"address=", Genode::Hex(address), " " "address=", Hex(address), " "
"value=", Genode::Hex(value), " " "value=", Hex(value), " "
"size=", Genode::Hex(size), " " "size=", Hex(size), " "
"denied - it is used by the platform driver."); "denied - it is used by the platform driver.");
return; return;
case Device_config::PCI_CMD_REG: /* COMMAND register - first byte */ case Device_config::PCI_CMD_REG: /* COMMAND register - first byte */
if (size == Access_size::ACCESS_16BIT) if (size == Access_size::ACCESS_16BIT)
@ -128,11 +129,11 @@ void Platform::Device_component::config_write(unsigned char address,
break; break;
[[fallthrough]]; [[fallthrough]];
default: default:
Genode::warning(_device_config, " write access to " warning(_device_config, " write access to "
"address=", Genode::Hex(address), " " "address=", Hex(address), " "
"value=", Genode::Hex(value), " " "value=", Hex(value), " "
"size=", Genode::Hex(size), " " "size=", Hex(size), " "
"got dropped"); "got dropped");
return; return;
} }
@ -144,7 +145,7 @@ void Platform::Device_component::config_write(unsigned char address,
catch (Out_of_ram) { throw; } catch (Out_of_ram) { throw; }
catch (Out_of_caps) { throw; } catch (Out_of_caps) { throw; }
catch (...) { catch (...) {
Genode::error("assignment to device failed"); error("assignment to device failed");
} }
_device_used = true; _device_used = true;
} }
@ -153,16 +154,14 @@ void Platform::Device_component::config_write(unsigned char address,
_device_config.DONT_TRACK_ACCESS); _device_config.DONT_TRACK_ACCESS);
} }
Genode::Irq_session_capability Platform::Device_component::irq(Genode::uint8_t id) Genode::Irq_session_capability Platform::Device_component::irq(uint8_t id)
{ {
if (id != 0) if (id != 0)
return Genode::Irq_session_capability(); return Irq_session_capability();
if (_irq_session) if (_irq_session)
return _irq_session->cap(); return _irq_session->cap();
using Genode::construct_at;
if (!_device_config.valid()) { if (!_device_config.valid()) {
/* Non PCI devices */ /* Non PCI devices */
_irq_session = construct_at<Irq_session_component>(_mem_irq_component, _irq_session = construct_at<Irq_session_component>(_mem_irq_component,
@ -174,8 +173,8 @@ Genode::Irq_session_capability Platform::Device_component::irq(Genode::uint8_t i
return _irq_session->cap(); return _irq_session->cap();
} }
Genode::uint16_t const msi_cap = _msi_cap(); uint16_t const msi_cap = _msi_cap();
Genode::uint16_t const msix_cap = _msix_cap(); uint16_t const msix_cap = _msix_cap();
_irq_session = construct_at<Irq_session_component>(_mem_irq_component, _irq_session = construct_at<Irq_session_component>(_mem_irq_component,
_configure_irq(_irq_line, msi_cap, msix_cap), _configure_irq(_irq_line, msi_cap, msix_cap),
@ -194,25 +193,25 @@ Genode::Irq_session_capability Platform::Device_component::irq(Genode::uint8_t i
} }
if (_irq_session->msi()) if (_irq_session->msi())
Genode::log(_device_config, " uses ", log(_device_config, " uses ",
msix_used ? "MSI-X " : "", msix_used ? "MSI-X " : "",
(msix_used && msi_cap) ? "(supports MSI) " : "", (msix_used && msi_cap) ? "(supports MSI) " : "",
msi_used ? "MSI ": "", msi_used ? "MSI ": "",
(msi_used && msix_cap) ? "(supports MSI-X) " : "", (msi_used && msix_cap) ? "(supports MSI-X) " : "",
(!msi_used && !msix_used) ? "no MSI/-X/IRQ " : "", (!msi_used && !msix_used) ? "no MSI/-X/IRQ " : "",
"vector ", Genode::Hex(_irq_session->msi_data()), ", " "vector ", Hex(_irq_session->msi_data()), ", "
"address ", Genode::Hex(_irq_session->msi_address())); "address ", Hex(_irq_session->msi_address()));
else else
Genode::log(_device_config, " uses IRQ, vector ", log(_device_config, " uses IRQ, vector ",
Genode::Hex(_irq_line), Hex(_irq_line),
(msi_cap || msix_cap) ? ", supports:" : "", (msi_cap || msix_cap) ? ", supports:" : "",
msi_cap ? " MSI" : "", msi_cap ? " MSI" : "",
msix_cap ? " MSI-X" : ""); msix_cap ? " MSI-X" : "");
return _irq_session->cap(); return _irq_session->cap();
} }
bool Platform::Device_component::_setup_msi(Genode::uint16_t const msi_cap) bool Platform::Device_component::_setup_msi(uint16_t const msi_cap)
{ {
try { try {
addr_t const msi_address = _irq_session->msi_address(); addr_t const msi_address = _irq_session->msi_address();
@ -245,7 +244,7 @@ bool Platform::Device_component::_setup_msi(Genode::uint16_t const msi_cap)
return false; return false;
} }
bool Platform::Device_component::_setup_msix(Genode::uint16_t const msix_cap) bool Platform::Device_component::_setup_msix(uint16_t const msix_cap)
{ {
try { try {
struct Table_pba : Register<32> struct Table_pba : Register<32>
@ -275,10 +274,10 @@ bool Platform::Device_component::_setup_msix(Genode::uint16_t const msix_cap)
if (slots * SIZEOF_MSI_TABLE_ENTRY > SIZE_IOMEM) if (slots * SIZEOF_MSI_TABLE_ENTRY > SIZE_IOMEM)
return false; return false;
Genode::uint64_t const msix_table_phys = res.base() + table_off; uint64_t const msix_table_phys = res.base() + table_off;
apply_msix_table(res, msix_table_phys, SIZE_IOMEM, apply_msix_table(res, msix_table_phys, SIZE_IOMEM,
[&](Genode::addr_t const msix_table) [&](addr_t const msix_table)
{ {
struct Msi_entry : public Mmio { struct Msi_entry : public Mmio {
Msi_entry(addr_t const base) : Mmio(base) { } Msi_entry(addr_t const base) : Mmio(base) { }
@ -313,11 +312,11 @@ bool Platform::Device_component::_setup_msix(Genode::uint16_t const msix_cap)
ctrl = _read_config_16(msix_cap + 2); ctrl = _read_config_16(msix_cap + 2);
return Msix_ctrl::Enable::get(ctrl); return Msix_ctrl::Enable::get(ctrl);
} catch (Genode::Out_of_caps) { } catch (Out_of_caps) {
Genode::warning("Out_of_caps during MSI-X enablement"); } warning("Out_of_caps during MSI-X enablement"); }
catch (Genode::Out_of_ram) { catch (Out_of_ram) {
Genode::warning("Out_of_ram during MSI-X enablement"); } warning("Out_of_ram during MSI-X enablement"); }
catch (...) { Genode::warning("MSI-X enablement failed"); } catch (...) { warning("MSI-X enablement failed"); }
return false; return false;
} }

View File

@ -11,7 +11,8 @@
* under the terms of the GNU Affero General Public License version 3. * under the terms of the GNU Affero General Public License version 3.
*/ */
#pragma once #ifndef _PCI_DEVICE_COMPONENT_H_
#define _PCI_DEVICE_COMPONENT_H_
/* base */ /* base */
#include <base/rpc_server.h> #include <base/rpc_server.h>
@ -35,12 +36,13 @@ namespace Platform {
typedef Registry<Registered<Device_config::Device_bars> > Device_bars_pool; typedef Registry<Registered<Device_config::Device_bars> > Device_bars_pool;
} }
class Platform::Device_component : public Genode::Rpc_object<Platform::Device>,
private Genode::List<Device_component>::Element class Platform::Device_component : public Rpc_object<Platform::Device>,
private List<Device_component>::Element
{ {
private: private:
friend class Genode::List<Device_component>; friend class List<Device_component>;
/* /*
* Noncopyable * Noncopyable
@ -48,42 +50,40 @@ class Platform::Device_component : public Genode::Rpc_object<Platform::Device>,
Device_component(Device_component const &); Device_component(Device_component const &);
Device_component &operator = (Device_component const &); Device_component &operator = (Device_component const &);
Genode::Env &_env; Env &_env;
Pci::Config::Delayer &_delayer; Pci::Config::Delayer &_delayer;
Device_bars_pool &_devices_bars; Device_bars_pool &_devices_bars;
Device_config _device_config { }; Device_config _device_config { };
Genode::addr_t _config_space; addr_t _config_space;
Config_access _config_access; Config_access _config_access;
Platform::Session_component &_session; Platform::Session_component &_session;
Irq_session_component *_irq_session = nullptr; Irq_session_component *_irq_session = nullptr;
unsigned short _irq_line; unsigned short _irq_line;
bool _device_used { false }; bool _device_used { false };
Allocator &_global_heap;
Genode::Allocator &_global_heap; class Io_mem : public Io_mem_connection,
private List<Io_mem>::Element
class Io_mem : public Genode::Io_mem_connection,
private Genode::List<Io_mem>::Element
{ {
private: private:
friend class Genode::List<Io_mem>; friend class List<Io_mem>;
friend class Platform::Device_component; friend class Platform::Device_component;
public: public:
Genode::addr_t const base; addr_t const base;
Genode::size_t const size; size_t const size;
Io_mem(Genode::Env &env, Genode::addr_t base, Io_mem(Env &env, addr_t base, size_t size, bool wc)
Genode::size_t size, bool wc)
: :
Genode::Io_mem_connection(env, base, size, wc), Io_mem_connection(env, base, size, wc),
base(base), size(size) base(base), size(size)
{ } { }
}; };
enum { enum {
IO_BLOCK_SIZE = sizeof(Genode::Io_port_connection) * IO_BLOCK_SIZE = sizeof(Io_port_connection) *
Device::NUM_RESOURCES + 32 + 8 * sizeof(void *), Device::NUM_RESOURCES + 32 + 8 * sizeof(void *),
IO_MEM_SIZE = sizeof(Io_mem) * IO_MEM_SIZE = sizeof(Io_mem) *
Device::NUM_RESOURCES + 32 + 8 * sizeof(void *), Device::NUM_RESOURCES + 32 + 8 * sizeof(void *),
@ -135,23 +135,24 @@ class Platform::Device_component : public Genode::Rpc_object<Platform::Device>,
}; };
Genode::Tslab<Genode::Io_port_connection, IO_BLOCK_SIZE> _slab_ioport; Tslab<Io_port_connection, IO_BLOCK_SIZE> _slab_ioport;
char _slab_ioport_block_data[IO_BLOCK_SIZE]; char _slab_ioport_block_data[IO_BLOCK_SIZE];
Genode::Tslab<Io_mem, IO_MEM_SIZE> _slab_iomem; Tslab<Io_mem, IO_MEM_SIZE> _slab_iomem;
char _slab_iomem_block_data[IO_MEM_SIZE]; char _slab_iomem_block_data[IO_MEM_SIZE];
char _mem_irq_component[sizeof(Irq_session_component)]; char _mem_irq_component[sizeof(Irq_session_component)];
Genode::Io_port_connection *_io_port_conn[Device::NUM_RESOURCES]; Io_port_connection *_io_port_conn[Device::NUM_RESOURCES];
/* list of requested resource chunks per BAR */ /* list of requested resource chunks per BAR */
Genode::List<Io_mem> _io_mem[Device::NUM_RESOURCES]; List<Io_mem> _io_mem[Device::NUM_RESOURCES];
struct Status : Genode::Register<8> { struct Status : Register<8>
{
struct Capabilities : Bitfield<4,1> { }; struct Capabilities : Bitfield<4,1> { };
inline static access_t read(Genode::uint8_t t) { return t; } inline static access_t read(uint8_t t) { return t; }
}; };
/** /**
@ -219,7 +220,7 @@ class Platform::Device_component : public Genode::Rpc_object<Platform::Device>,
uint8_t cap = _read_config_16(PCI_CAP_OFFSET); uint8_t cap = _read_config_16(PCI_CAP_OFFSET);
for (Genode::uint16_t val = 0; cap; cap = val >> 8) { for (uint16_t val = 0; cap; cap = val >> 8) {
val = _read_config_16(cap); val = _read_config_16(cap);
if ((val & 0xff) != target_cap) if ((val & 0xff) != target_cap)
continue; continue;
@ -237,9 +238,6 @@ class Platform::Device_component : public Genode::Rpc_object<Platform::Device>,
unsigned _configure_irq(unsigned irq, uint16_t const msi_cap, unsigned _configure_irq(unsigned irq, uint16_t const msi_cap,
uint16_t const msix_cap) uint16_t const msix_cap)
{ {
using Genode::uint16_t;
using Genode::uint8_t;
uint8_t pin = _device_config.read(_config_access, PCI_IRQ_PIN, uint8_t pin = _device_config.read(_config_access, PCI_IRQ_PIN,
Platform::Device::ACCESS_8BIT); Platform::Device::ACCESS_8BIT);
if (!pin) if (!pin)
@ -248,8 +246,8 @@ class Platform::Device_component : public Genode::Rpc_object<Platform::Device>,
/* lookup rewrite information as provided by acpi table */ /* lookup rewrite information as provided by acpi table */
uint16_t irq_r = Irq_routing::rewrite(_device_config.bdf(), pin); uint16_t irq_r = Irq_routing::rewrite(_device_config.bdf(), pin);
if (irq_r) { if (irq_r) {
Genode::log(_device_config, " adjust IRQ as reported by ACPI: ", log(_device_config, " adjust IRQ as reported by ACPI: ",
irq, " -> ", irq_r); irq, " -> ", irq_r);
_irq_line = irq = irq_r; _irq_line = irq = irq_r;
} }
@ -294,16 +292,16 @@ class Platform::Device_component : public Genode::Rpc_object<Platform::Device>,
_device_config.disable_bus_master_dma(_config_access); _device_config.disable_bus_master_dma(_config_access);
} }
bool _setup_msi(Genode::uint16_t); bool _setup_msi(uint16_t);
bool _setup_msix(Genode::uint16_t); bool _setup_msix(uint16_t);
template <typename FUNC> template <typename FUNC>
void apply_msix_table(Pci::Resource const &lookup, void apply_msix_table(Pci::Resource const &lookup,
Genode::addr_t const msix_table_phys, addr_t const msix_table_phys,
Genode::size_t const msix_table_size, size_t const msix_table_size,
FUNC const &fn) FUNC const &fn)
{ {
Genode::uint8_t max = sizeof(_io_mem) / sizeof(_io_mem[0]); uint8_t max = sizeof(_io_mem) / sizeof(_io_mem[0]);
for (unsigned i = 0; i < max; ++i) { for (unsigned i = 0; i < max; ++i) {
Pci::Resource res = _device_config.resource(i); Pci::Resource res = _device_config.resource(i);
@ -319,7 +317,7 @@ class Platform::Device_component : public Genode::Rpc_object<Platform::Device>,
msix_table_phys + msix_table_size <= io_mem->base + io_mem->size)) msix_table_phys + msix_table_size <= io_mem->base + io_mem->size))
continue; continue;
Genode::size_t const offset = msix_table_phys - io_mem->base; size_t const offset = msix_table_phys - io_mem->base;
Attached_dataspace mem_io(_env.rm(), io_mem->dataspace()); Attached_dataspace mem_io(_env.rm(), io_mem->dataspace());
@ -464,12 +462,12 @@ class Platform::Device_component : public Genode::Rpc_object<Platform::Device>,
/** /**
* Constructor for PCI devices * Constructor for PCI devices
*/ */
Device_component(Genode::Env &env, Device_component(Env &env,
Device_config device_config, Genode::addr_t addr, Device_config device_config, addr_t addr,
Config_access &config_access, Config_access &config_access,
Platform::Session_component &session, Platform::Session_component &session,
Genode::Allocator &md_alloc, Allocator &md_alloc,
Genode::Allocator &global_heap, Allocator &global_heap,
Pci::Config::Delayer &delayer, Pci::Config::Delayer &delayer,
Device_bars_pool &devices_bars) Device_bars_pool &devices_bars)
: :
@ -495,10 +493,10 @@ class Platform::Device_component : public Genode::Rpc_object<Platform::Device>,
/** /**
* Constructor for non PCI devices * Constructor for non PCI devices
*/ */
Device_component(Genode::Env &env, Device_component(Env &env,
Genode::Attached_io_mem_dataspace &pciconf, Attached_io_mem_dataspace &pciconf,
Platform::Session_component &session, unsigned irq, Platform::Session_component &session, unsigned irq,
Genode::Allocator &global_heap, Allocator &global_heap,
Pci::Config::Delayer &delayer, Pci::Config::Delayer &delayer,
Device_bars_pool &devices_bars) Device_bars_pool &devices_bars)
: :
@ -517,7 +515,6 @@ class Platform::Device_component : public Genode::Rpc_object<Platform::Device>,
_io_port_conn[i] = nullptr; _io_port_conn[i] = nullptr;
} }
/** /**
* De-constructor * De-constructor
*/ */
@ -530,11 +527,11 @@ class Platform::Device_component : public Genode::Rpc_object<Platform::Device>,
for (unsigned i = 0; i < Device::NUM_RESOURCES; i++) { for (unsigned i = 0; i < Device::NUM_RESOURCES; i++) {
if (_io_port_conn[i]) if (_io_port_conn[i])
Genode::destroy(_slab_ioport, _io_port_conn[i]); destroy(_slab_ioport, _io_port_conn[i]);
while (Io_mem * io_mem = _io_mem[i].first()) { while (Io_mem * io_mem = _io_mem[i].first()) {
_io_mem[i].remove(io_mem); _io_mem[i].remove(io_mem);
Genode::destroy(_slab_iomem, io_mem); destroy(_slab_iomem, io_mem);
} }
} }
@ -549,7 +546,7 @@ class Platform::Device_component : public Genode::Rpc_object<Platform::Device>,
****************************************/ ****************************************/
Device_config device_config() const { return _device_config; } Device_config device_config() const { return _device_config; }
Genode::addr_t config_space() const { return _config_space; } addr_t config_space() const { return _config_space; }
virtual String<5> name() const { return "PCI"; } virtual String<5> name() const { return "PCI"; }
@ -598,12 +595,11 @@ class Platform::Device_component : public Genode::Rpc_object<Platform::Device>,
void config_write(unsigned char address, unsigned value, void config_write(unsigned char address, unsigned value,
Access_size size) override; Access_size size) override;
Genode::Irq_session_capability irq(Genode::uint8_t) override; Irq_session_capability irq(uint8_t) override;
Genode::Io_port_session_capability io_port(Genode::uint8_t) override; Io_port_session_capability io_port(uint8_t) override;
Genode::Io_mem_session_capability io_mem(Genode::uint8_t, Io_mem_session_capability io_mem(uint8_t, Cache, addr_t, size_t) override;
Genode::Cache,
Genode::addr_t,
Genode::size_t) override;
}; };
#endif /* _PCI_DEVICE_COMPONENT_H_ */

View File

@ -20,17 +20,14 @@
#include "pci_config_access.h" #include "pci_config_access.h"
namespace Platform { namespace Pci { namespace Platform { namespace Pci { struct Resource; } }
struct Resource;
} }
class Platform::Pci::Resource class Platform::Pci::Resource
{ {
public: public:
struct Bar : Genode::Register<32> struct Bar : Register<32>
{ {
struct Space : Bitfield<0,1> { enum { MEM = 0, PORT = 1 }; }; struct Space : Bitfield<0,1> { enum { MEM = 0, PORT = 1 }; };
@ -61,7 +58,8 @@ class Platform::Pci::Resource
/* PORT or MEM32 resource */ /* PORT or MEM32 resource */
Resource(uint32_t bar, uint32_t size) Resource(uint32_t bar, uint32_t size)
: _bar{bar, 0}, _size(mem() ? Bar::mem_size(size, ~0) : Bar::port_size(size)) :
_bar{bar, 0}, _size(mem() ? Bar::mem_size(size, ~0) : Bar::port_size(size))
{ } { }
/* MEM64 resource */ /* MEM64 resource */
@ -84,9 +82,9 @@ class Platform::Pci::Resource
return Device::Resource((unsigned)_bar[0], (unsigned)_size); return Device::Resource((unsigned)_bar[0], (unsigned)_size);
} }
void print(Genode::Output &out) const void print(Output &out) const
{ {
Genode::print(out, Genode::Hex_range(base(), size())); Genode::print(out, Hex_range(base(), size()));
} }
}; };
@ -271,7 +269,7 @@ namespace Platform {
*/ */
Pci::Bdf bdf() const { return _bdf; } Pci::Bdf bdf() const { return _bdf; }
void print(Genode::Output &out) const { Genode::print(out, bdf()); } void print(Output &out) const { Genode::print(out, bdf()); }
/** /**
* Accessor functions for device information * Accessor functions for device information
@ -366,26 +364,25 @@ namespace Platform {
} }
}; };
class Config_space : private Genode::List<Config_space>::Element class Config_space : private List<Config_space>::Element
{ {
private: private:
friend class Genode::List<Config_space>; friend class List<Config_space>;
Genode::uint32_t _bdf_start; uint32_t _bdf_start;
Genode::uint32_t _func_count; uint32_t _func_count;
Genode::addr_t _base; addr_t _base;
public: public:
using Genode::List<Config_space>::Element::next; using List<Config_space>::Element::next;
Config_space(Genode::uint32_t bdf_start, Config_space(uint32_t bdf_start, uint32_t func_count, addr_t base)
Genode::uint32_t func_count, Genode::addr_t base)
: :
_bdf_start(bdf_start), _func_count(func_count), _base(base) {} _bdf_start(bdf_start), _func_count(func_count), _base(base) {}
Genode::addr_t lookup_config_space(Pci::Bdf const bdf) addr_t lookup_config_space(Pci::Bdf const bdf)
{ {
if ((_bdf_start <= bdf.value()) && (bdf.value() <= _bdf_start + _func_count - 1)) if ((_bdf_start <= bdf.value()) && (bdf.value() <= _bdf_start + _func_count - 1))
return _base + (unsigned(bdf.value()) << 12); return _base + (unsigned(bdf.value()) << 12);

View File

@ -11,7 +11,8 @@
* under the terms of the GNU Affero General Public License version 3. * under the terms of the GNU Affero General Public License version 3.
*/ */
#pragma once #ifndef _PCI_SESSION_COMPONENT_H_
#define _PCI_SESSION_COMPONENT_H_
/* base */ /* base */
#include <base/attached_rom_dataspace.h> #include <base/attached_rom_dataspace.h>
@ -37,9 +38,8 @@
#include "pci_config_access.h" #include "pci_config_access.h"
#include "pci_device_component.h" #include "pci_device_component.h"
typedef Genode::Ram_dataspace_capability Ram_capability;
namespace Platform { namespace Platform {
unsigned short bridge_bdf(unsigned char bus); unsigned short bridge_bdf(unsigned char bus);
class Pci_buses; class Pci_buses;
@ -49,35 +49,37 @@ namespace Platform {
class Session_component; class Session_component;
} }
class Platform::Ram_dataspace : public Genode::List<Ram_dataspace>::Element {
class Platform::Ram_dataspace : public List<Ram_dataspace>::Element
{
private: private:
Ram_capability const _cap; Ram_dataspace_capability const _cap;
public: public:
Ram_dataspace(Ram_capability c) : _cap(c) { }
bool match(const Ram_capability &cap) const { Ram_dataspace(Ram_dataspace_capability c) : _cap(c) { }
bool match(const Ram_dataspace_capability &cap) const {
return cap.local_name() == _cap.local_name(); } return cap.local_name() == _cap.local_name(); }
Ram_capability cap() const { return _cap; } Ram_dataspace_capability cap() const { return _cap; }
}; };
class Platform::Rmrr : public Genode::List<Platform::Rmrr>::Element
class Platform::Rmrr : public List<Platform::Rmrr>::Element
{ {
public: public:
class Bdf : public Genode::List<Bdf>::Element { class Bdf : public List<Bdf>::Element {
private: private:
Genode::uint8_t _bus, _dev, _func; uint8_t _bus, _dev, _func;
public: public:
Bdf(Genode::uint8_t bus, Genode::uint8_t dev, Bdf(uint8_t bus, uint8_t dev, uint8_t func)
Genode::uint8_t func)
: _bus(bus), _dev(dev), _func(func) { } : _bus(bus), _dev(dev), _func(func) { }
bool match(Pci::Bdf const bdf) bool match(Pci::Bdf const bdf)
@ -89,22 +91,19 @@ class Platform::Rmrr : public Genode::List<Platform::Rmrr>::Element
private: private:
Genode::uint64_t const _start, _end; uint64_t const _start, _end;
Genode::Io_mem_dataspace_capability _cap { }; Io_mem_dataspace_capability _cap { };
Genode::List<Bdf> _bdf_list { }; List<Bdf> _bdf_list { };
Genode::Constructible<Genode::Io_mem_connection> _io_mem { }; Constructible<Io_mem_connection> _io_mem { };
public: public:
Rmrr(Genode::uint64_t start, Genode::uint64_t end) Rmrr(uint64_t start, uint64_t end) : _start(start), _end(end) { }
: _start(start), _end(end)
{ }
Genode::Io_mem_dataspace_capability match(Genode::Env &env, Io_mem_dataspace_capability match(Env &env, Device_config config)
Device_config config)
{ {
for (Bdf *bdf = _bdf_list.first(); bdf; bdf = bdf->next()) { for (Bdf *bdf = _bdf_list.first(); bdf; bdf = bdf->next()) {
if (!bdf->match(config.bdf())) if (!bdf->match(config.bdf()))
@ -117,16 +116,16 @@ class Platform::Rmrr : public Genode::List<Platform::Rmrr>::Element
_cap = _io_mem->dataspace(); _cap = _io_mem->dataspace();
return _cap; return _cap;
} }
return Genode::Io_mem_dataspace_capability(); return Io_mem_dataspace_capability();
} }
addr_t start() const { return _start; } addr_t start() const { return _start; }
void add(Bdf * bdf) { _bdf_list.insert(bdf); } void add(Bdf * bdf) { _bdf_list.insert(bdf); }
static Genode::List<Rmrr> *list() static List<Rmrr> *list()
{ {
static Genode::List<Rmrr> _list; static List<Rmrr> _list;
return &_list; return &_list;
} }
}; };
@ -136,9 +135,9 @@ class Platform::Pci_buses
{ {
private: private:
Genode::Bit_array<Device_config::MAX_BUSES> _valid { }; Bit_array<Device_config::MAX_BUSES> _valid { };
void scan_bus(Config_access &, Genode::Allocator &, Device_bars_pool &, void scan_bus(Config_access &, Allocator &, Device_bars_pool &,
unsigned char bus = 0); unsigned char bus = 0);
bool _bus_valid(int bus) bool _bus_valid(int bus)
@ -151,8 +150,8 @@ class Platform::Pci_buses
public: public:
Pci_buses(Genode::Allocator &heap, Pci_buses(Allocator &heap,
Genode::Attached_io_mem_dataspace &pciconf, Attached_io_mem_dataspace &pciconf,
Device_bars_pool &devices_bars) Device_bars_pool &devices_bars)
{ {
Config_access c(pciconf); Config_access c(pciconf);
@ -203,37 +202,36 @@ class Platform::Pci_buses
}; };
class Platform::Session_component : public Genode::Rpc_object<Session> class Platform::Session_component : public Rpc_object<Session>
{ {
private: private:
Genode::Env &_env; Env &_env;
Genode::Attached_rom_dataspace &_config; Attached_rom_dataspace &_config;
Genode::Attached_io_mem_dataspace &_pciconf; Attached_io_mem_dataspace &_pciconf;
Genode::addr_t const _pciconf_base; addr_t const _pciconf_base;
Genode::Ram_quota_guard _ram_guard; Ram_quota_guard _ram_guard;
Genode::Cap_quota_guard _cap_guard; Cap_quota_guard _cap_guard;
Genode::Constrained_ram_allocator _env_ram { Constrained_ram_allocator _env_ram { _env.pd(), _ram_guard, _cap_guard };
_env.pd(), _ram_guard, _cap_guard }; Heap _md_alloc;
Genode::Heap _md_alloc; Session_label const _label;
Genode::Session_label const _label; List<Device_component> _device_list { };
Genode::List<Device_component> _device_list { }; Platform::Pci_buses &_pci_bus;
Platform::Pci_buses &_pci_bus; Heap &_global_heap;
Genode::Heap &_global_heap; Pci::Config::Delayer &_delayer;
Pci::Config::Delayer &_delayer; Device_bars_pool &_devices_bars;
Device_bars_pool &_devices_bars; bool _iommu;
bool _iommu; bool _msi_usage { true };
bool _msi_usage { true };
/** /**
* Registry of RAM dataspaces allocated by the session * Registry of RAM dataspaces allocated by the session
*/ */
Genode::List<Platform::Ram_dataspace> _ram_caps { }; List<Platform::Ram_dataspace> _ram_caps { };
void _insert(Ram_capability cap) { void _insert(Ram_dataspace_capability cap) {
_ram_caps.insert(new (_md_alloc) Platform::Ram_dataspace(cap)); } _ram_caps.insert(new (_md_alloc) Platform::Ram_dataspace(cap)); }
bool _owned(Ram_capability cap) bool _owned(Ram_dataspace_capability cap)
{ {
for (Ram_dataspace *ds = _ram_caps.first(); ds; ds = ds->next()) for (Ram_dataspace *ds = _ram_caps.first(); ds; ds = ds->next())
if (ds->match(cap)) if (ds->match(cap))
@ -242,7 +240,7 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
return false; return false;
} }
bool _remove(Ram_capability cap) bool _remove(Ram_dataspace_capability cap)
{ {
for (Platform::Ram_dataspace *ds = _ram_caps.first(); ds; for (Platform::Ram_dataspace *ds = _ram_caps.first(); ds;
ds = ds->next()) { ds = ds->next()) {
@ -263,14 +261,14 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
Device_config::MAX_DEVICES * Device_config::MAX_DEVICES *
Device_config::MAX_FUNCTIONS }; Device_config::MAX_FUNCTIONS };
static Genode::Bit_array<MAX_PCI_DEVICES> bdf_in_use; static Bit_array<MAX_PCI_DEVICES> bdf_in_use;
/** /**
* List containing extended PCI config space information * List containing extended PCI config space information
*/ */
static Genode::List<Config_space> &config_space_list() static List<Config_space> &config_space_list()
{ {
static Genode::List<Config_space> config_space; static List<Config_space> config_space;
return config_space; return config_space;
} }
@ -279,10 +277,8 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
* the corresponding extended 4K PCI config space address. * the corresponding extended 4K PCI config space address.
* A io mem dataspace is created and returned. * A io mem dataspace is created and returned.
*/ */
Genode::addr_t lookup_config_space(Pci::Bdf const bdf) addr_t lookup_config_space(Pci::Bdf const bdf)
{ {
using namespace Genode;
addr_t config_space = ~0UL; /* invalid */ addr_t config_space = ~0UL; /* invalid */
Config_space *e = config_space_list().first(); Config_space *e = config_space_list().first();
@ -292,7 +288,7 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
return config_space; return config_space;
} }
typedef Genode::String<32> Alias_name; typedef String<32> Alias_name;
/* /*
* List of aliases for PCI Class/Subclas/Prog I/F triple used * List of aliases for PCI Class/Subclas/Prog I/F triple used
@ -300,8 +296,6 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
*/ */
unsigned class_subclass_prog(Alias_name const &name) unsigned class_subclass_prog(Alias_name const &name)
{ {
using namespace Genode;
static struct { static struct {
const char * alias; const char * alias;
uint8_t pci_class, pci_subclass, pci_progif; uint8_t pci_class, pci_subclass, pci_progif;
@ -335,15 +329,13 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
*/ */
bool permit_device(const char * name) bool permit_device(const char * name)
{ {
using namespace Genode;
Session_policy const policy { _label, _config.xml() }; Session_policy const policy { _label, _config.xml() };
try { try {
policy.for_each_sub_node("device", [&] (Xml_node dev) { policy.for_each_sub_node("device", [&] (Xml_node dev) {
/* enforce restriction based on name name */ /* enforce restriction based on name name */
if (dev.attribute_value("name", Genode::String<10>()) == name) if (dev.attribute_value("name", String<10>()) == name)
/* found identical match - permit access */ /* found identical match - permit access */
throw true; throw true;
}); });
@ -384,8 +376,6 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
*/ */
bool permit_device(Pci::Bdf const bdf, unsigned const class_code) bool permit_device(Pci::Bdf const bdf, unsigned const class_code)
{ {
using namespace Genode;
try { try {
Session_policy const policy { _label, _config.xml() }; Session_policy const policy { _label, _config.xml() };
@ -425,13 +415,11 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
*/ */
bool find_dev_in_policy(const char * dev_name, bool once = true) bool find_dev_in_policy(const char * dev_name, bool once = true)
{ {
using namespace Genode;
try { try {
_config.xml().for_each_sub_node("policy", [&] (Xml_node policy) { _config.xml().for_each_sub_node("policy", [&] (Xml_node policy) {
policy.for_each_sub_node("device", [&] (Xml_node device) { policy.for_each_sub_node("device", [&] (Xml_node device) {
typedef Genode::String<10> Name; typedef String<10> Name;
if (device.attribute_value("name", Name()) == dev_name) { if (device.attribute_value("name", Name()) == dev_name) {
if (once) if (once)
@ -450,8 +438,6 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
*/ */
bool find_dev_in_policy(Pci::Bdf const bdf, bool once = true) bool find_dev_in_policy(Pci::Bdf const bdf, bool once = true)
{ {
using namespace Genode;
try { try {
Xml_node xml = _config.xml(); Xml_node xml = _config.xml();
xml.for_each_sub_node("policy", [&] (Xml_node policy) { xml.for_each_sub_node("policy", [&] (Xml_node policy) {
@ -478,25 +464,25 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
/** /**
* Constructor * Constructor
*/ */
Session_component(Genode::Env &env, Session_component(Env &env,
Genode::Attached_rom_dataspace &config, Attached_rom_dataspace &config,
Genode::Attached_io_mem_dataspace &pciconf, Attached_io_mem_dataspace &pciconf,
Genode::addr_t pciconf_base, addr_t pciconf_base,
Platform::Pci_buses &buses, Platform::Pci_buses &buses,
Genode::Heap &global_heap, Heap &global_heap,
Pci::Config::Delayer &delayer, Pci::Config::Delayer &delayer,
Device_bars_pool &devices_bars, Device_bars_pool &devices_bars,
char const *args, char const *args,
bool const iommu) bool const iommu)
: :
_env(env), _env(env),
_config(config), _config(config),
_pciconf(pciconf), _pciconf(pciconf),
_pciconf_base(pciconf_base), _pciconf_base(pciconf_base),
_ram_guard(Genode::ram_quota_from_args(args)), _ram_guard(ram_quota_from_args(args)),
_cap_guard(Genode::cap_quota_from_args(args)), _cap_guard(cap_quota_from_args(args)),
_md_alloc(_env_ram, env.rm()), _md_alloc(_env_ram, env.rm()),
_label(Genode::label_from_args(args)), _label(label_from_args(args)),
_pci_bus(buses), _pci_bus(buses),
_global_heap(global_heap), _global_heap(global_heap),
_delayer(delayer), _delayer(delayer),
@ -504,7 +490,7 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
_iommu(iommu) _iommu(iommu)
{ {
/* subtract the RPC session and session dataspace capabilities */ /* subtract the RPC session and session dataspace capabilities */
_cap_guard.withdraw(Genode::Cap_quota{2}); _cap_guard.withdraw(Cap_quota{2});
check_for_policy(); check_for_policy();
} }
@ -513,36 +499,33 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
{ {
Session_policy const policy { _label, _config.xml() }; Session_policy const policy { _label, _config.xml() };
typedef Genode::String<10> Mode; typedef String<10> Mode;
_msi_usage = policy.attribute_value("irq_mode", Mode()) != "nomsi"; _msi_usage = policy.attribute_value("irq_mode", Mode()) != "nomsi";
/* check policy for non-pci devices */ /* check policy for non-pci devices */
policy.for_each_sub_node("device", [&] (Genode::Xml_node device_node) { policy.for_each_sub_node("device", [&] (Xml_node device_node) {
if (!device_node.has_attribute("name")) { if (!device_node.has_attribute("name")) {
Genode::error("'", _label, "' - device node " error("'", _label, "' - device node " "misses 'name' attribute");
"misses 'name' attribute"); throw Service_denied();
throw Genode::Service_denied();
} }
typedef Genode::String<16> Name; typedef String<16> Name;
Name const name = device_node.attribute_value("name", Name()); Name const name = device_node.attribute_value("name", Name());
enum { DOUBLET = false }; enum { DOUBLET = false };
if (find_dev_in_policy(name.string(), DOUBLET)) { if (find_dev_in_policy(name.string(), DOUBLET)) {
Genode::error("'", _label, "' - device '", name, "' " error("'", _label, "' - device '", name, "' "
"is part of more than one policy"); "is part of more than one policy");
throw Genode::Service_denied(); throw Service_denied();
} }
}); });
/* pci devices */ /* pci devices */
policy.for_each_sub_node("pci", [&] (Genode::Xml_node node) { policy.for_each_sub_node("pci", [&] (Xml_node node) {
enum { INVALID_CLASS = 0x1000000U }; enum { INVALID_CLASS = 0x1000000U };
using Genode::Xml_attribute;
/** /**
* Valid input is either a triple of 'bus', 'device', * Valid input is either a triple of 'bus', 'device',
* 'function' attributes or a single 'class' attribute. * 'function' attributes or a single 'class' attribute.
@ -553,16 +536,16 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
Alias_name const alias = node.attribute_value("class", Alias_name()); Alias_name const alias = node.attribute_value("class", Alias_name());
if (class_subclass_prog(alias) >= INVALID_CLASS) { if (class_subclass_prog(alias) >= INVALID_CLASS) {
Genode::error("'", _label, "' - invalid 'class' ", error("'", _label, "' - invalid 'class' ",
"attribute '", alias, "'"); "attribute '", alias, "'");
throw Genode::Service_denied(); throw Service_denied();
} }
/* sanity check that 'class' is the only attribute */ /* sanity check that 'class' is the only attribute */
try { try {
node.attribute(1); node.attribute(1);
Genode::error("'", _label, "' - attributes beside 'class' detected"); error("'", _label, "' - attributes beside 'class' detected");
throw Genode::Service_denied(); throw Service_denied();
} }
catch (Xml_attribute::Nonexistent_attribute) { } catch (Xml_attribute::Nonexistent_attribute) { }
@ -573,27 +556,26 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
/* no 'class' attribute - now check for valid bdf triple */ /* no 'class' attribute - now check for valid bdf triple */
try { try {
node.attribute(3); node.attribute(3);
Genode::error("'", _label, "' - " error("'", _label, "' - " "invalid number of pci node attributes");
"invalid number of pci node attributes"); throw Service_denied();
throw Genode::Service_denied();
} catch (Xml_attribute::Nonexistent_attribute) { } } catch (Xml_attribute::Nonexistent_attribute) { }
if (_bdf_exactly_specified(node)) { if (_bdf_exactly_specified(node)) {
if (!_bdf_attributes_in_valid_range(node)) { if (!_bdf_attributes_in_valid_range(node)) {
Genode::error("'", _label, "' - " error("'", _label, "' - "
"invalid pci node attributes for bdf"); "invalid pci node attributes for bdf");
throw Genode::Service_denied(); throw Service_denied();
} }
Pci::Bdf const bdf = _bdf_from_xml(node); Pci::Bdf const bdf = _bdf_from_xml(node);
enum { DOUBLET = false }; enum { DOUBLET = false };
if (find_dev_in_policy(bdf, DOUBLET)) { if (find_dev_in_policy(bdf, DOUBLET)) {
Genode::error("'", _label, "' - device '", bdf, "' " error("'", _label, "' - device '", bdf, "' "
"is part of more than one policy"); "is part of more than one policy");
throw Genode::Service_denied(); throw Service_denied();
} }
} }
}); });
@ -650,19 +632,18 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
} }
void upgrade_resources(Genode::Session::Resources resources) void upgrade_resources(Session::Resources resources)
{ {
_ram_guard.upgrade(resources.ram_quota); _ram_guard.upgrade(resources.ram_quota);
_cap_guard.upgrade(resources.cap_quota); _cap_guard.upgrade(resources.cap_quota);
} }
static void add_config_space(Genode::uint32_t bdf_start, static void add_config_space(uint32_t bdf_start,
Genode::uint32_t func_count, uint32_t func_count,
Genode::addr_t base, addr_t base,
Genode::Allocator &heap) Allocator &heap)
{ {
using namespace Genode;
Config_space * space = Config_space * space =
new (heap) Config_space(bdf_start, func_count, base); new (heap) Config_space(bdf_start, func_count, base);
config_space_list().insert(space); config_space_list().insert(space);
@ -740,8 +721,7 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
} }
/* lookup if we have a extended pci config space */ /* lookup if we have a extended pci config space */
Genode::addr_t config_space = addr_t config_space = lookup_config_space(config.bdf());
lookup_config_space(config.bdf());
/* /*
* A device was found. Create a new device component for the * A device was found. Create a new device component for the
@ -757,9 +737,8 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
try { try {
/* if more than one driver uses the device - warn about */ /* if more than one driver uses the device - warn about */
if (bdf_in_use.get(config.bdf().value(), 1)) if (bdf_in_use.get(config.bdf().value(), 1))
Genode::error("Device ", config, error("Device ", config, " is used by more than one driver - "
" is used by more than one driver - " "session '", _label, "'.");
"session '", _label, "'.");
else else
bdf_in_use.set(config.bdf().value(), 1); bdf_in_use.set(config.bdf().value(), 1);
@ -800,8 +779,6 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
void assign_device(Device_component * device) void assign_device(Device_component * device)
{ {
using namespace Genode;
if (!device || device->config_space() == ~0UL || !_iommu) if (!device || device->config_space() == ~0UL || !_iommu)
return; return;
@ -822,7 +799,7 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
device->device_config().bdf().value()); device->device_config().bdf().value());
} catch (...) { } catch (...) {
Genode::error("assignment to device pd or of RMRR region failed"); error("assignment to device pd or of RMRR region failed");
} }
} }
@ -830,10 +807,10 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
* De-/Allocation of dma capable dataspaces * De-/Allocation of dma capable dataspaces
*/ */
Ram_capability alloc_dma_buffer(Genode::size_t const size) override Ram_dataspace_capability alloc_dma_buffer(size_t const size) override
{ {
Ram_capability ram_cap = _env_ram.alloc(size, Genode::UNCACHED); Ram_dataspace_capability ram_cap = _env_ram.alloc(size, UNCACHED);
addr_t const dma_addr = Dataspace_client(ram_cap).phys_addr(); addr_t const dma_addr = Dataspace_client(ram_cap).phys_addr();
if (!ram_cap.valid()) if (!ram_cap.valid())
return ram_cap; return ram_cap;
@ -843,16 +820,16 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
_insert(ram_cap); _insert(ram_cap);
} catch (Out_of_ram) { } catch (Out_of_ram) {
_env_ram.free(ram_cap); _env_ram.free(ram_cap);
throw Genode::Out_of_ram(); throw Out_of_ram();
} catch (Out_of_caps) { } catch (Out_of_caps) {
_env_ram.free(ram_cap); _env_ram.free(ram_cap);
throw Genode::Out_of_caps(); throw Out_of_caps();
} }
return ram_cap; return ram_cap;
} }
void free_dma_buffer(Ram_capability ram_cap) override void free_dma_buffer(Ram_dataspace_capability ram_cap) override
{ {
if (!ram_cap.valid() || !_remove(ram_cap)) if (!ram_cap.valid() || !_remove(ram_cap))
return; return;
@ -860,7 +837,7 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
_env_ram.free(ram_cap); _env_ram.free(ram_cap);
} }
Genode::addr_t dma_addr(Ram_capability ram_cap) override addr_t dma_addr(Ram_dataspace_capability ram_cap) override
{ {
if (!ram_cap.valid() || !_owned(ram_cap)) if (!ram_cap.valid() || !_owned(ram_cap))
return 0; return 0;
@ -868,26 +845,26 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
return Dataspace_client(ram_cap).phys_addr(); return Dataspace_client(ram_cap).phys_addr();
} }
Device_capability device(String const &name) override; Device_capability device(Device_name const &name) override;
}; };
class Platform::Root : public Genode::Root_component<Session_component> class Platform::Root : public Root_component<Session_component>
{ {
private: private:
Genode::Env &_env; Env &_env;
Genode::Attached_rom_dataspace &_config; Attached_rom_dataspace &_config;
Genode::Constructible<Genode::Attached_io_mem_dataspace> _pci_confspace { }; Constructible<Attached_io_mem_dataspace> _pci_confspace { };
Genode::addr_t _pci_confspace_base = 0; addr_t _pci_confspace_base = 0;
Constructible<Expanding_reporter> _pci_reporter { };
Genode::Constructible<Genode::Expanding_reporter> _pci_reporter { }; Heap _heap { _env.ram(), _env.rm() };
Genode::Heap _heap { _env.ram(), _env.rm() }; Device_bars_pool _devices_bars { };
Device_bars_pool _devices_bars { }; Constructible<Platform::Pci_buses> _buses { };
Genode::Constructible<Platform::Pci_buses> _buses { };
bool _iommu { false }; bool _iommu { false };
bool _pci_reported { false }; bool _pci_reported { false };
@ -899,13 +876,11 @@ class Platform::Root : public Genode::Root_component<Session_component>
void usleep(uint64_t us) override { Timer::Connection::usleep(us); } void usleep(uint64_t us) override { Timer::Connection::usleep(us); }
} _delayer { _env }; } _delayer { _env };
Genode::Registry<Genode::Registered<Session_component> > _sessions { }; Registry<Registered<Session_component> > _sessions { };
void _parse_report_rom(Genode::Env &env, const char * acpi_rom, void _parse_report_rom(Env &env, const char * acpi_rom,
bool acpi_platform) bool acpi_platform)
{ {
using namespace Genode;
Xml_node xml_acpi(acpi_rom); Xml_node xml_acpi(acpi_rom);
if (!xml_acpi.has_type("acpi")) if (!xml_acpi.has_type("acpi"))
throw 1; throw 1;
@ -1044,7 +1019,8 @@ class Platform::Root : public Genode::Root_component<Session_component>
void _construct_buses() void _construct_buses()
{ {
Genode::Dataspace_client ds_pci_mmio(_pci_confspace->cap()); Dataspace_client ds_pci_mmio(_pci_confspace->cap());
uint64_t const phys_addr = _pci_confspace_base; uint64_t const phys_addr = _pci_confspace_base;
uint64_t const phys_size = ds_pci_mmio.size(); uint64_t const phys_size = ds_pci_mmio.size();
uint64_t mmio_size = 0x10000000UL; /* max MMCONF memory */ uint64_t mmio_size = 0x10000000UL; /* max MMCONF memory */
@ -1069,7 +1045,7 @@ class Platform::Root : public Genode::Root_component<Session_component>
_pci_confspace.construct(_env, phys_addr, mmio_size); _pci_confspace.construct(_env, phys_addr, mmio_size);
/* got memory - try again */ /* got memory - try again */
break; break;
} catch (Genode::Service_denied) { } catch (Service_denied) {
/* decrease by one bus memory size */ /* decrease by one bus memory size */
mmio_size -= 0x1000UL * 32 * 8; mmio_size -= 0x1000UL * 32 * 8;
} }
@ -1087,25 +1063,21 @@ class Platform::Root : public Genode::Root_component<Session_component>
{ {
try { try {
return new (md_alloc()) return new (md_alloc())
Genode::Registered<Session_component>(_sessions, _env, Registered<Session_component>(_sessions, _env, _config,
_config, *_pci_confspace,
*_pci_confspace, _pci_confspace_base,
_pci_confspace_base, *_buses, _heap, _delayer,
*_buses, _heap, _devices_bars, args, _iommu);
_delayer,
_devices_bars, args,
_iommu);
} }
catch (Genode::Session_policy::No_policy_defined) { catch (Session_policy::No_policy_defined) {
Genode::error("Invalid session request, no matching policy for ", error("Invalid session request, no matching policy for ",
"'", Genode::label_from_args(args).string(), "'"); "'", label_from_args(args).string(), "'");
throw Genode::Service_denied(); throw Service_denied();
} }
} }
void _upgrade_session(Session_component *s, const char *args) override { void _upgrade_session(Session_component *s, const char *args) override {
s->upgrade_resources(Genode::session_resources_from_args(args)); } s->upgrade_resources(session_resources_from_args(args)); }
public: public:
@ -1117,28 +1089,25 @@ class Platform::Root : public Genode::Root_component<Session_component>
* \param md_alloc meta-data allocator for allocating PCI-session * \param md_alloc meta-data allocator for allocating PCI-session
* components and PCI-device components * components and PCI-device components
*/ */
Root(Genode::Env &env, Genode::Allocator &md_alloc, Root(Env &env, Allocator &md_alloc, Attached_rom_dataspace &config,
Genode::Attached_rom_dataspace &config, char const *acpi_rom, bool acpi_platform)
const char *acpi_rom,
bool acpi_platform)
: :
Genode::Root_component<Session_component>(&env.ep().rpc_ep(), Root_component<Session_component>(&env.ep().rpc_ep(), &md_alloc),
&md_alloc),
_env(env), _config(config) _env(env), _config(config)
{ {
try { try {
_parse_report_rom(env, acpi_rom, acpi_platform); _parse_report_rom(env, acpi_rom, acpi_platform);
} catch (...) { } catch (...) {
Genode::error("ACPI report parsing error."); error("ACPI report parsing error.");
throw; throw;
} }
if (Platform::Bridge::root_bridge_bdf < Platform::Bridge::INVALID_ROOT_BRIDGE) { if (Platform::Bridge::root_bridge_bdf < Platform::Bridge::INVALID_ROOT_BRIDGE) {
Device_config config(Pci::Bdf::from_value(Platform::Bridge::root_bridge_bdf)); Device_config config(Pci::Bdf::from_value(Platform::Bridge::root_bridge_bdf));
Genode::log("Root bridge: ", config); log("Root bridge: ", config);
} else } else {
Genode::warning("Root bridge: unknown"); warning("Root bridge: unknown");
}
_construct_buses(); _construct_buses();
@ -1158,7 +1127,7 @@ class Platform::Root : public Genode::Root_component<Session_component>
Config_access config_access(*_pci_confspace); Config_access config_access(*_pci_confspace);
Device_config config; Device_config config;
_pci_reporter->generate([&] (Genode::Reporter::Xml_generator &xml) { _pci_reporter->generate([&] (Reporter::Xml_generator &xml) {
int bus = 0, device = 0, function = -1; int bus = 0, device = 0, function = -1;
/* iterate over pci devices */ /* iterate over pci devices */
@ -1172,9 +1141,6 @@ class Platform::Root : public Genode::Root_component<Session_component>
device = config.bdf().device; device = config.bdf().device;
function = config.bdf().function; function = config.bdf().function;
using Genode::String;
using Genode::Hex;
xml.node("device", [&] () { xml.node("device", [&] () {
xml.attribute("bus" , String<5>(Hex(bus))); xml.attribute("bus" , String<5>(Hex(bus)));
xml.attribute("device" , String<5>(Hex(device))); xml.attribute("device" , String<5>(Hex(device)));
@ -1189,11 +1155,11 @@ class Platform::Root : public Genode::Root_component<Session_component>
try { try {
config.read(config_access, PCI_STATUS, Platform::Device::ACCESS_16BIT); config.read(config_access, PCI_STATUS, Platform::Device::ACCESS_16BIT);
Genode::uint8_t cap = config.read(config_access, uint8_t cap = config.read(config_access,
PCI_CAP_OFFSET, PCI_CAP_OFFSET,
Platform::Device::ACCESS_8BIT); Platform::Device::ACCESS_8BIT);
for (Genode::uint16_t val = 0; cap; cap = val >> 8) { for (uint16_t val = 0; cap; cap = val >> 8) {
val = config.read(config_access, cap, Platform::Device::ACCESS_16BIT); val = config.read(config_access, cap, Platform::Device::ACCESS_16BIT);
xml.attribute("cap", String<8>(Hex(val & 0xff))); xml.attribute("cap", String<8>(Hex(val & 0xff)));
} }
@ -1217,3 +1183,5 @@ class Platform::Root : public Genode::Root_component<Session_component>
}); });
} }
}; };
#endif /* _PCI_SESSION_COMPONENT_H_ */

View File

@ -39,7 +39,7 @@ unsigned short Platform::bridge_bdf(unsigned char bus)
} }
void Platform::Pci_buses::scan_bus(Config_access &config_access, void Platform::Pci_buses::scan_bus(Config_access &config_access,
Genode::Allocator &heap, Allocator &heap,
Device_bars_pool &devices_bars, Device_bars_pool &devices_bars,
unsigned char bus) unsigned char bus)
{ {
@ -131,6 +131,5 @@ void Platform::Pci_buses::scan_bus(Config_access &config_access,
using Platform::Session_component; using Platform::Session_component;
using Genode::Bit_array;
Bit_array<Session_component::MAX_PCI_DEVICES> Session_component::bdf_in_use; Genode::Bit_array<Session_component::MAX_PCI_DEVICES> Session_component::bdf_in_use;