mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-31 00:24:51 +00:00
parent
f358fcbda6
commit
14d8627186
@ -288,10 +288,10 @@ void Platform::Irq_session_component::sigh(Genode::Signal_context_capability sig
|
||||
|
||||
unsigned short Platform::Irq_routing::rewrite(Pci::Bdf const bdf, unsigned char pin)
|
||||
{
|
||||
unsigned const bridge_bdf_bus = Platform::bridge_bdf(bdf.bus());
|
||||
unsigned const bridge_bdf_bus = Platform::bridge_bdf(bdf.bus);
|
||||
|
||||
for (Irq_routing *i = list()->first(); i; i = i->next()) {
|
||||
if ((bdf.device() == i->_device) && (pin - 1 == i->_device_pin) &&
|
||||
if ((bdf.device == i->_device) && (pin - 1 == i->_device_pin) &&
|
||||
(i->_bridge_bdf == bridge_bdf_bus))
|
||||
return i->_gsi;
|
||||
}
|
||||
|
@ -28,31 +28,32 @@ namespace Platform { namespace Pci { struct Bdf; struct Config; } }
|
||||
|
||||
struct Platform::Pci::Bdf
|
||||
{
|
||||
struct Bdf_register : Register<16>
|
||||
unsigned bus, device, function;
|
||||
|
||||
static Bdf from_value(uint16_t const bdf)
|
||||
{
|
||||
struct Function : Bitfield< 0, 3> { };
|
||||
struct Device : Bitfield< 3, 5> { };
|
||||
struct Bus : Bitfield< 8, 8> { };
|
||||
};
|
||||
|
||||
uint16_t bdf;
|
||||
|
||||
Bdf(uint16_t bdf) : bdf(bdf) { }
|
||||
|
||||
Bdf(unsigned bus, unsigned device, unsigned function) : bdf(0)
|
||||
{
|
||||
Bdf_register::Bus::set(bdf, bus);
|
||||
Bdf_register::Device::set(bdf, device);
|
||||
Bdf_register::Function::set(bdf, function);
|
||||
return Bdf { .bus = (bdf >> 8) & 0xffu,
|
||||
.device = (bdf >> 3) & 0x1fu,
|
||||
.function = bdf & 0x07u };
|
||||
}
|
||||
|
||||
uint8_t bus() const { return Bdf_register::Bus::get(bdf); }
|
||||
uint8_t device() const { return Bdf_register::Device::get(bdf); }
|
||||
uint8_t function() const { return Bdf_register::Function::get(bdf); }
|
||||
uint16_t value() const {
|
||||
return ((bus & 0xff) << 8) | ((device & 0x1f) << 3) | (function & 7); }
|
||||
|
||||
bool operator == (Bdf const &other) const { return bdf == other.bdf; }
|
||||
bool operator == (Bdf const &other) const {
|
||||
return value() == other.value(); }
|
||||
|
||||
void print(Genode::Output &out) const
|
||||
{
|
||||
using Genode::print;
|
||||
using Genode::Hex;
|
||||
print(out, Hex(bus, Hex::Prefix::OMIT_PREFIX, Hex::Pad::PAD),
|
||||
":", Hex(device, Hex::Prefix::OMIT_PREFIX, Hex::Pad::PAD),
|
||||
".", Hex(function, Hex::Prefix::OMIT_PREFIX));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
namespace Platform {
|
||||
|
||||
class Config_access
|
||||
@ -69,7 +70,7 @@ namespace Platform {
|
||||
*/
|
||||
unsigned _dev_base(Pci::Bdf const bdf)
|
||||
{
|
||||
return unsigned(bdf.bdf) << 12;
|
||||
return unsigned(bdf.value()) << 12;
|
||||
}
|
||||
|
||||
Genode::Bit_array<256> _used { };
|
||||
|
@ -282,7 +282,7 @@ class Platform::Device_component : public Genode::Rpc_object<Platform::Device>,
|
||||
* as we have no driver which will switch it on again
|
||||
*/
|
||||
if (_device_config.pci_bridge() ||
|
||||
_device_config.bdf() == Pci::Bdf(Platform::Bridge::root_bridge_bdf))
|
||||
_device_config.bdf() == Pci::Bdf::from_value(Platform::Bridge::root_bridge_bdf))
|
||||
return;
|
||||
|
||||
_device_config.disable_bus_master_dma(_config_access);
|
||||
@ -554,9 +554,9 @@ class Platform::Device_component : public Genode::Rpc_object<Platform::Device>,
|
||||
void bus_address(unsigned char *bus, unsigned char *dev,
|
||||
unsigned char *fn) override
|
||||
{
|
||||
*bus = _device_config.bdf().bus();
|
||||
*dev = _device_config.bdf().device();
|
||||
*fn = _device_config.bdf().function();
|
||||
*bus = _device_config.bdf().bus;
|
||||
*dev = _device_config.bdf().device;
|
||||
*fn = _device_config.bdf().function;
|
||||
}
|
||||
|
||||
unsigned short vendor_id() override { return _device_config.vendor_id(); }
|
||||
|
@ -174,7 +174,8 @@ namespace Platform {
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Device_config() : _bdf(0, 0, 0), _vendor_id(INVALID_VENDOR) { }
|
||||
Device_config() : _bdf({ .bus = 0, .device = 0, .function = 0 }) {
|
||||
_vendor_id = INVALID_VENDOR; }
|
||||
|
||||
Device_config(Pci::Bdf bdf) : _bdf(bdf) { }
|
||||
|
||||
@ -198,8 +199,8 @@ namespace Platform {
|
||||
* device. Note, the mf bit of function 1-7 is not significant
|
||||
* and may be set or unset.
|
||||
*/
|
||||
if (bdf.function() != 0) {
|
||||
Pci::Bdf const dev(bdf.bus(), bdf.device(), 0);
|
||||
if (bdf.function != 0) {
|
||||
Pci::Bdf const dev { .bus = bdf.bus, .device = bdf.device, .function = 0 };
|
||||
if (!(pci_config->read(dev, 0xe, Device::ACCESS_8BIT) & 0x80)) {
|
||||
_vendor_id = INVALID_VENDOR;
|
||||
return;
|
||||
@ -270,14 +271,7 @@ namespace Platform {
|
||||
*/
|
||||
Pci::Bdf bdf() const { return _bdf; }
|
||||
|
||||
void print(Genode::Output &out) const
|
||||
{
|
||||
using Genode::print;
|
||||
using Genode::Hex;
|
||||
print(out, Hex(_bdf.bus(), Hex::Prefix::OMIT_PREFIX, Hex::Pad::PAD),
|
||||
":", Hex(_bdf.device(), Hex::Prefix::OMIT_PREFIX, Hex::Pad::PAD),
|
||||
".", Hex(_bdf.function(), Hex::Prefix::OMIT_PREFIX));
|
||||
}
|
||||
void print(Genode::Output &out) const { Genode::print(out, bdf()); }
|
||||
|
||||
/**
|
||||
* Accessor functions for device information
|
||||
@ -393,8 +387,8 @@ namespace Platform {
|
||||
|
||||
Genode::addr_t lookup_config_space(Pci::Bdf const bdf)
|
||||
{
|
||||
if ((_bdf_start <= bdf.bdf) && (bdf.bdf <= _bdf_start + _func_count - 1))
|
||||
return _base + (unsigned(bdf.bdf) << 12);
|
||||
if ((_bdf_start <= bdf.value()) && (bdf.value() <= _bdf_start + _func_count - 1))
|
||||
return _base + (unsigned(bdf.value()) << 12);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
@ -82,8 +82,8 @@ class Platform::Rmrr : public Genode::List<Platform::Rmrr>::Element
|
||||
|
||||
bool match(Pci::Bdf const bdf)
|
||||
{
|
||||
return bdf.bus() == _bus && bdf.device() == _dev &&
|
||||
bdf.function() == _func;
|
||||
return bdf.bus == _bus && bdf.device == _dev &&
|
||||
bdf.function == _func;
|
||||
}
|
||||
};
|
||||
|
||||
@ -172,7 +172,7 @@ class Platform::Pci_buses
|
||||
* \retval true device was found
|
||||
* \retval false no device was found
|
||||
*/
|
||||
bool find_next(int bus, int device, int function,
|
||||
bool find_next(unsigned bus, unsigned device, unsigned function,
|
||||
Device_config *out_device_config,
|
||||
Config_access *config_access)
|
||||
{
|
||||
@ -184,7 +184,7 @@ class Platform::Pci_buses
|
||||
for (; function < Device_config::MAX_FUNCTIONS; function++) {
|
||||
|
||||
/* read config space */
|
||||
Pci::Bdf const bdf(bus, device, function);
|
||||
Pci::Bdf const bdf { .bus = bus, .device = device, .function = function };
|
||||
Device_config config(bdf, config_access);
|
||||
|
||||
if (config.valid()) {
|
||||
@ -345,29 +345,14 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
||||
&& node.has_attribute("function");
|
||||
}
|
||||
|
||||
struct Bdf
|
||||
static Pci::Bdf _bdf_from_xml(Xml_node node)
|
||||
{
|
||||
unsigned b, d, f;
|
||||
|
||||
bool equals(Bdf const &other) const
|
||||
{
|
||||
return other.b == b && other.d == d && other.f == f;
|
||||
}
|
||||
|
||||
void print(Genode::Output &out) const
|
||||
{
|
||||
Genode::print(out, Genode::Hex(b), ":", Genode::Hex(d), ".", f);
|
||||
}
|
||||
};
|
||||
|
||||
static Bdf _bdf_from_xml(Xml_node node)
|
||||
{
|
||||
return Bdf { .b = node.attribute_value("bus", 0U),
|
||||
.d = node.attribute_value("device", 0U),
|
||||
.f = node.attribute_value("function", 0U) };
|
||||
return Pci::Bdf { .bus = node.attribute_value("bus", 0U),
|
||||
.device = node.attribute_value("device", 0U),
|
||||
.function = node.attribute_value("function", 0U) };
|
||||
}
|
||||
|
||||
static bool _bdf_attributes_in_valid_range(Xml_node node)
|
||||
static bool _bdf_attributes_in_valid_range(Xml_node const &node)
|
||||
{
|
||||
return _bdf_exactly_specified(node)
|
||||
&& (node.attribute_value("bus", 0U) < Device_config::MAX_BUSES)
|
||||
@ -375,15 +360,15 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
||||
&& (node.attribute_value("function", 0U) < Device_config::MAX_FUNCTIONS);
|
||||
}
|
||||
|
||||
static bool _bdf_matches(Xml_node node, Bdf bdf)
|
||||
static bool _bdf_matches(Xml_node const &node, Pci::Bdf const &bdf)
|
||||
{
|
||||
return _bdf_from_xml(node).equals(bdf);
|
||||
return _bdf_from_xml(node) == bdf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check according session policy device usage
|
||||
*/
|
||||
bool permit_device(Bdf const bdf, unsigned class_code)
|
||||
bool permit_device(Pci::Bdf const bdf, unsigned const class_code)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
@ -447,7 +432,7 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
||||
/**
|
||||
* Lookup a given device name.
|
||||
*/
|
||||
bool find_dev_in_policy(Bdf const bdf, bool once = true)
|
||||
bool find_dev_in_policy(Pci::Bdf const bdf, bool once = true)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
@ -574,7 +559,7 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
||||
throw Genode::Service_denied();
|
||||
}
|
||||
|
||||
Bdf const bdf = _bdf_from_xml(node);
|
||||
Pci::Bdf const bdf = _bdf_from_xml(node);
|
||||
|
||||
enum { DOUBLET = false };
|
||||
if (find_dev_in_policy(bdf, DOUBLET)) {
|
||||
@ -662,9 +647,9 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
||||
|
||||
if (prev) {
|
||||
Device_config config = prev->device_config();
|
||||
bus = config.bdf().bus();
|
||||
device = config.bdf().device();
|
||||
function = config.bdf().function();
|
||||
bus = config.bdf().bus;
|
||||
device = config.bdf().device;
|
||||
function = config.bdf().function;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -680,18 +665,18 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
||||
return Device_capability();
|
||||
|
||||
/* get new bdf values */
|
||||
bus = config.bdf().bus();
|
||||
device = config.bdf().device();
|
||||
function = config.bdf().function();
|
||||
bus = config.bdf().bus;
|
||||
device = config.bdf().device;
|
||||
function = config.bdf().function;
|
||||
|
||||
/* if filter of driver don't match skip and continue */
|
||||
if ((config.class_code() ^ device_class) & class_mask)
|
||||
continue;
|
||||
|
||||
/* check that policy permit access to the matched device */
|
||||
if (permit_device(Bdf { (unsigned)bus,
|
||||
(unsigned)device,
|
||||
(unsigned)function },
|
||||
if (permit_device(Pci::Bdf { (unsigned)bus,
|
||||
(unsigned)device,
|
||||
(unsigned)function },
|
||||
config.class_code()))
|
||||
break;
|
||||
}
|
||||
@ -713,12 +698,12 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
||||
|
||||
try {
|
||||
/* if more than one driver uses the device - warn about */
|
||||
if (bdf_in_use.get(config.bdf().bdf, 1))
|
||||
if (bdf_in_use.get(config.bdf().value(), 1))
|
||||
Genode::error("Device ", config,
|
||||
" is used by more than one driver - "
|
||||
"session '", _label, "'.");
|
||||
else
|
||||
bdf_in_use.set(config.bdf().bdf, 1);
|
||||
bdf_in_use.set(config.bdf().value(), 1);
|
||||
|
||||
return _env.ep().rpc_ep().manage(dev);
|
||||
} catch (...) {
|
||||
@ -740,8 +725,8 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
||||
return;
|
||||
|
||||
if (device->device_config().valid()) {
|
||||
if (bdf_in_use.get(device->device_config().bdf().bdf, 1))
|
||||
bdf_in_use.clear(device->device_config().bdf().bdf, 1);
|
||||
if (bdf_in_use.get(device->device_config().bdf().value(), 1))
|
||||
bdf_in_use.clear(device->device_config().bdf().value(), 1);
|
||||
}
|
||||
|
||||
_device_list.remove(device);
|
||||
@ -764,7 +749,7 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
||||
|
||||
try {
|
||||
addr_t const base_ecam = Dataspace_client(_pciconf.cap()).phys_addr();
|
||||
addr_t const base_offset = 0x1000UL * device->device_config().bdf().bdf;
|
||||
addr_t const base_offset = 0x1000UL * device->device_config().bdf().value();
|
||||
|
||||
if (base_ecam + base_offset != device->config_space())
|
||||
throw 1;
|
||||
@ -776,7 +761,7 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
||||
}
|
||||
|
||||
_device_pd.assign_pci(_pciconf.cap(), base_offset,
|
||||
device->device_config().bdf().bdf);
|
||||
device->device_config().bdf().value());
|
||||
|
||||
} catch (...) {
|
||||
Genode::error("assignment to device pd or of RMRR region failed");
|
||||
@ -863,11 +848,9 @@ class Platform::Root : public Genode::Root_component<Session_component>
|
||||
Session_component::add_config_space(bdf_start, func_count,
|
||||
base, _heap);
|
||||
|
||||
Pci::Bdf const bdf_s(bdf_start);
|
||||
Pci::Bdf const bdf_l(bdf_start + func_count - 1);
|
||||
|
||||
Device_config const bdf_first(bdf_s);
|
||||
Device_config const bdf_last(bdf_l);
|
||||
Device_config const bdf_first(Pci::Bdf::from_value(bdf_start));
|
||||
Device_config const bdf_last(Pci::Bdf::from_value(bdf_start +
|
||||
func_count - 1));
|
||||
|
||||
addr_t const memory_size = 0x1000UL * func_count;
|
||||
|
||||
@ -947,7 +930,9 @@ class Platform::Root : public Genode::Root_component<Session_component>
|
||||
path.attribute("dev") .value(dev);
|
||||
path.attribute("func").value(func);
|
||||
|
||||
Pci::Bdf const bdf(bus, dev, func);
|
||||
Pci::Bdf const bdf = { .bus = bus, .device = dev,
|
||||
.function = func };
|
||||
|
||||
Device_config bridge(bdf, &config_access);
|
||||
if (bridge.pci_bridge())
|
||||
/* PCI bridge spec 3.2.5.3, 3.2.5.4 */
|
||||
@ -1073,7 +1058,7 @@ class Platform::Root : public Genode::Root_component<Session_component>
|
||||
}
|
||||
|
||||
if (Platform::Bridge::root_bridge_bdf < Platform::Bridge::INVALID_ROOT_BRIDGE) {
|
||||
Device_config config(Pci::Bdf(Platform::Bridge::root_bridge_bdf));
|
||||
Device_config config(Pci::Bdf::from_value(Platform::Bridge::root_bridge_bdf));
|
||||
Genode::log("Root bridge: ", config);
|
||||
} else
|
||||
Genode::warning("Root bridge: unknown");
|
||||
@ -1098,9 +1083,9 @@ class Platform::Root : public Genode::Root_component<Session_component>
|
||||
&config_access))
|
||||
return;
|
||||
|
||||
bus = config.bdf().bus();
|
||||
device = config.bdf().device();
|
||||
function = config.bdf().function();
|
||||
bus = config.bdf().bus;
|
||||
device = config.bdf().device;
|
||||
function = config.bdf().function;
|
||||
|
||||
using Genode::String;
|
||||
using Genode::Hex;
|
||||
|
@ -43,11 +43,13 @@ void Platform::Pci_buses::scan_bus(Config_access &config_access,
|
||||
Device_bars_pool &devices_bars,
|
||||
unsigned char bus)
|
||||
{
|
||||
for (int dev = 0; dev < Device_config::MAX_DEVICES; ++dev) {
|
||||
for (int fun = 0; fun < Device_config::MAX_FUNCTIONS; ++fun) {
|
||||
for (unsigned dev = 0; dev < Device_config::MAX_DEVICES; ++dev) {
|
||||
for (unsigned fun = 0; fun < Device_config::MAX_FUNCTIONS; ++fun) {
|
||||
|
||||
Pci::Bdf const bdf { .bus = bus, .device = dev, .function = fun };
|
||||
|
||||
/* read config space */
|
||||
Device_config config(Pci::Bdf(bus, dev, fun), &config_access);
|
||||
Device_config config(bdf, &config_access);
|
||||
|
||||
/* remember Device BARs required after power off and/or reset */
|
||||
if (config.valid()) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user