mirror of
https://github.com/genodelabs/genode.git
synced 2025-05-31 14:40:54 +00:00
platform_drv: introduce structured PCI BDF type
Replace explicit usage of bus, device, function arguments to methods or variables all over the code by a single data type. It eases the reading of and shorten the code. Issue #3963
This commit is contained in:
parent
f57519397b
commit
ebf7f8f599
@ -286,13 +286,12 @@ void Platform::Irq_session_component::sigh(Genode::Signal_context_capability sig
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned short Platform::Irq_routing::rewrite(unsigned char bus, unsigned char dev,
|
unsigned short Platform::Irq_routing::rewrite(Pci::Bdf const bdf, unsigned char pin)
|
||||||
unsigned char, unsigned char pin)
|
|
||||||
{
|
{
|
||||||
unsigned const bridge_bdf_bus = Platform::bridge_bdf(bus);
|
unsigned const bridge_bdf_bus = Platform::bridge_bdf(bdf.bus());
|
||||||
|
|
||||||
for (Irq_routing *i = list()->first(); i; i = i->next()) {
|
for (Irq_routing *i = list()->first(); i; i = i->next()) {
|
||||||
if ((dev == i->_device) && (pin - 1 == i->_device_pin) &&
|
if ((bdf.device() == i->_device) && (pin - 1 == i->_device_pin) &&
|
||||||
(i->_bridge_bdf == bridge_bdf_bus))
|
(i->_bridge_bdf == bridge_bdf_bus))
|
||||||
return i->_gsi;
|
return i->_gsi;
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include <irq_session/connection.h>
|
#include <irq_session/connection.h>
|
||||||
|
|
||||||
/* platform local includes */
|
/* platform local includes */
|
||||||
|
#include <pci_config_access.h>
|
||||||
#include <irq_proxy.h>
|
#include <irq_proxy.h>
|
||||||
|
|
||||||
|
|
||||||
@ -181,8 +182,7 @@ class Platform::Irq_routing : public Genode::List<Platform::Irq_routing>::Elemen
|
|||||||
_device_pin(device_pin)
|
_device_pin(device_pin)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
static unsigned short rewrite(unsigned char bus, unsigned char dev,
|
static unsigned short rewrite(Pci::Bdf, unsigned char pin);
|
||||||
unsigned char func, unsigned char pin);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _X86__IRQ_H_ */
|
#endif /* _X86__IRQ_H_ */
|
||||||
|
@ -15,13 +15,44 @@
|
|||||||
#ifndef _X86_PCI_CONFIG_ACCESS_H_
|
#ifndef _X86_PCI_CONFIG_ACCESS_H_
|
||||||
#define _X86_PCI_CONFIG_ACCESS_H_
|
#define _X86_PCI_CONFIG_ACCESS_H_
|
||||||
|
|
||||||
#include <util/bit_array.h>
|
|
||||||
#include <base/attached_io_mem_dataspace.h>
|
#include <base/attached_io_mem_dataspace.h>
|
||||||
#include <base/attached_rom_dataspace.h>
|
#include <base/attached_rom_dataspace.h>
|
||||||
#include <platform_device/platform_device.h>
|
#include <platform_device/platform_device.h>
|
||||||
|
#include <util/bit_array.h>
|
||||||
|
#include <util/mmio.h>
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
|
namespace Platform { namespace Pci { struct Bdf; } }
|
||||||
|
|
||||||
|
|
||||||
|
struct Platform::Pci::Bdf
|
||||||
|
{
|
||||||
|
struct Bdf_register : Register<16>
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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); }
|
||||||
|
|
||||||
|
bool operator == (Bdf const &other) const { return bdf == other.bdf; }
|
||||||
|
};
|
||||||
|
|
||||||
namespace Platform {
|
namespace Platform {
|
||||||
|
|
||||||
class Config_access
|
class Config_access
|
||||||
@ -34,17 +65,11 @@ namespace Platform {
|
|||||||
/**
|
/**
|
||||||
* Calculate device offset from BDF
|
* Calculate device offset from BDF
|
||||||
*
|
*
|
||||||
* \param bus target PCI bus ID (0..255)
|
|
||||||
* \param device target device ID (0..31)
|
|
||||||
* \param function target function ID (0..7)
|
|
||||||
*
|
|
||||||
* \return device base address
|
* \return device base address
|
||||||
*/
|
*/
|
||||||
unsigned _dev_base(int bus, int device, int function)
|
unsigned _dev_base(Pci::Bdf const bdf)
|
||||||
{
|
{
|
||||||
return ((bus << 20) |
|
return unsigned(bdf.bdf) << 12;
|
||||||
(device << 15) |
|
|
||||||
(function << 12));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Genode::Bit_array<256> _used { };
|
Genode::Bit_array<256> _used { };
|
||||||
@ -72,9 +97,7 @@ namespace Platform {
|
|||||||
/**
|
/**
|
||||||
* Read value from config space of specified device/function
|
* Read value from config space of specified device/function
|
||||||
*
|
*
|
||||||
* \param bus target PCI bus ID
|
* \param bdf target PCI bus, device & function ID
|
||||||
* \param device target device ID
|
|
||||||
* \param function target function ID
|
|
||||||
* \param addr target byte within targeted PCI config space
|
* \param addr target byte within targeted PCI config space
|
||||||
* \param size bit width of read access
|
* \param size bit width of read access
|
||||||
*
|
*
|
||||||
@ -82,12 +105,11 @@ namespace Platform {
|
|||||||
*
|
*
|
||||||
* There is no range check for the input values.
|
* There is no range check for the input values.
|
||||||
*/
|
*/
|
||||||
unsigned read(int bus, int device, int function,
|
unsigned read(Pci::Bdf const bdf, unsigned char const addr,
|
||||||
unsigned char addr, Device::Access_size size,
|
Device::Access_size const size, bool const track = true)
|
||||||
bool track = true)
|
|
||||||
{
|
{
|
||||||
unsigned ret;
|
unsigned ret;
|
||||||
unsigned const offset = _dev_base(bus, device, function) + addr;
|
unsigned const offset = _dev_base(bdf) + addr;
|
||||||
char const * const field = _pciconf.local_addr<char>() + offset;
|
char const * const field = _pciconf.local_addr<char>() + offset;
|
||||||
|
|
||||||
if (offset >= _pciconf_size)
|
if (offset >= _pciconf_size)
|
||||||
@ -129,20 +151,18 @@ namespace Platform {
|
|||||||
/**
|
/**
|
||||||
* Write to config space of specified device/function
|
* Write to config space of specified device/function
|
||||||
*
|
*
|
||||||
* \param bus target PCI bus ID
|
* \param bdf target PCI bus, device & function ID
|
||||||
* \param device target device ID
|
|
||||||
* \param function target function ID
|
|
||||||
* \param addr target byte within targeted PCI config space
|
* \param addr target byte within targeted PCI config space
|
||||||
* \param value value to be written
|
* \param value value to be written
|
||||||
* \param size bit width of write access
|
* \param size bit width of write access
|
||||||
*
|
*
|
||||||
* There is no range check for the input values.
|
* There is no range check for the input values.
|
||||||
*/
|
*/
|
||||||
void write(int bus, int device, int function, unsigned char addr,
|
void write(Pci::Bdf const bdf, unsigned char const addr,
|
||||||
unsigned value, Device::Access_size size,
|
unsigned const value, Device::Access_size const size,
|
||||||
bool track = true)
|
bool const track = true)
|
||||||
{
|
{
|
||||||
unsigned const offset = _dev_base(bus, device, function) + addr;
|
unsigned const offset = _dev_base(bdf) + addr;
|
||||||
char const * const field = _pciconf.local_addr<char>() + offset;
|
char const * const field = _pciconf.local_addr<char>() + offset;
|
||||||
|
|
||||||
if (offset >= _pciconf_size)
|
if (offset >= _pciconf_size)
|
||||||
|
@ -165,10 +165,7 @@ class Platform::Device_component : public Genode::Rpc_object<Platform::Device>,
|
|||||||
return Irq_session_component::INVALID_IRQ;
|
return Irq_session_component::INVALID_IRQ;
|
||||||
|
|
||||||
/* 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.bus_number(),
|
uint16_t irq_r = Irq_routing::rewrite(_device_config.bdf(), pin);
|
||||||
_device_config.device_number(),
|
|
||||||
_device_config.function_number(),
|
|
||||||
pin);
|
|
||||||
if (irq_r) {
|
if (irq_r) {
|
||||||
Genode::log(_device_config, " adjust IRQ as reported by ACPI: ",
|
Genode::log(_device_config, " adjust IRQ as reported by ACPI: ",
|
||||||
irq, " -> ", irq_r);
|
irq, " -> ", irq_r);
|
||||||
@ -353,9 +350,9 @@ class Platform::Device_component : public Genode::Rpc_object<Platform::Device>,
|
|||||||
void bus_address(unsigned char *bus, unsigned char *dev,
|
void bus_address(unsigned char *bus, unsigned char *dev,
|
||||||
unsigned char *fn) override
|
unsigned char *fn) override
|
||||||
{
|
{
|
||||||
*bus = _device_config.bus_number();
|
*bus = _device_config.bdf().bus();
|
||||||
*dev = _device_config.device_number();
|
*dev = _device_config.bdf().device();
|
||||||
*fn = _device_config.function_number();
|
*fn = _device_config.bdf().function();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned short vendor_id() override { return _device_config.vendor_id(); }
|
unsigned short vendor_id() override { return _device_config.vendor_id(); }
|
||||||
|
@ -97,9 +97,7 @@ namespace Platform {
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
uint8_t _bus = 0;
|
Pci::Bdf _bdf;
|
||||||
uint8_t _device = 0;
|
|
||||||
uint8_t _function = 0; /* location at PCI bus */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Information provided by the PCI config space
|
* Information provided by the PCI config space
|
||||||
@ -147,29 +145,22 @@ namespace Platform {
|
|||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
Device_config() : _vendor_id(INVALID_VENDOR) { }
|
Device_config() : _bdf(0, 0, 0), _vendor_id(INVALID_VENDOR) { }
|
||||||
|
|
||||||
Device_config(unsigned bdf)
|
Device_config(Pci::Bdf bdf) : _bdf(bdf) { }
|
||||||
:
|
|
||||||
_bus((bdf >> 8) & 0xff),
|
|
||||||
_device((bdf >> 3) & 0x1f),
|
|
||||||
_function(bdf & 0x7)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
Device_config(int bus, int device, int function,
|
Device_config(Pci::Bdf bdf, Config_access *pci_config) : _bdf(bdf)
|
||||||
Config_access *pci_config):
|
|
||||||
_bus(bus), _device(device), _function(function)
|
|
||||||
{
|
{
|
||||||
_vendor_id = pci_config->read(bus, device, function, 0, Device::ACCESS_16BIT);
|
_vendor_id = pci_config->read(bdf, 0, Device::ACCESS_16BIT);
|
||||||
|
|
||||||
/* break here if device is invalid */
|
/* break here if device is invalid */
|
||||||
if (_vendor_id == INVALID_VENDOR)
|
if (_vendor_id == INVALID_VENDOR)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_device_id = pci_config->read(bus, device, function, 2, Device::ACCESS_16BIT);
|
_device_id = pci_config->read(bdf, 2, Device::ACCESS_16BIT);
|
||||||
_class_code = pci_config->read(bus, device, function, 8, Device::ACCESS_32BIT) >> 8;
|
_class_code = pci_config->read(bdf, 8, Device::ACCESS_32BIT) >> 8;
|
||||||
_class_code &= 0xffffff;
|
_class_code &= 0xffffff;
|
||||||
_header_type = pci_config->read(bus, device, function, 0xe, Device::ACCESS_8BIT);
|
_header_type = pci_config->read(bdf, 0xe, Device::ACCESS_8BIT);
|
||||||
_header_type &= 0x7f;
|
_header_type &= 0x7f;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -178,10 +169,12 @@ namespace Platform {
|
|||||||
* device. Note, the mf bit of function 1-7 is not significant
|
* device. Note, the mf bit of function 1-7 is not significant
|
||||||
* and may be set or unset.
|
* and may be set or unset.
|
||||||
*/
|
*/
|
||||||
if (function != 0
|
if (bdf.function() != 0) {
|
||||||
&& !(pci_config->read(bus, device, 0, 0xe, Device::ACCESS_8BIT) & 0x80)) {
|
Pci::Bdf const dev(bdf.bus(), bdf.device(), 0);
|
||||||
_vendor_id = INVALID_VENDOR;
|
if (!(pci_config->read(dev, 0xe, Device::ACCESS_8BIT) & 0x80)) {
|
||||||
return;
|
_vendor_id = INVALID_VENDOR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -200,7 +193,7 @@ namespace Platform {
|
|||||||
|
|
||||||
/* read base-address register value */
|
/* read base-address register value */
|
||||||
unsigned const bar_value =
|
unsigned const bar_value =
|
||||||
pci_config->read(bus, device, function, bar_idx, Device::ACCESS_32BIT);
|
pci_config->read(bdf, bar_idx, Device::ACCESS_32BIT);
|
||||||
|
|
||||||
/* skip invalid resource BARs */
|
/* skip invalid resource BARs */
|
||||||
if (bar_value == ~0U || bar_value == 0U) {
|
if (bar_value == ~0U || bar_value == 0U) {
|
||||||
@ -216,9 +209,9 @@ namespace Platform {
|
|||||||
* corresponding to the resource size. Finally, we write
|
* corresponding to the resource size. Finally, we write
|
||||||
* back the bar-address value as assigned by the BIOS.
|
* back the bar-address value as assigned by the BIOS.
|
||||||
*/
|
*/
|
||||||
pci_config->write(bus, device, function, bar_idx, ~0, Device::ACCESS_32BIT);
|
pci_config->write(bdf, bar_idx, ~0, Device::ACCESS_32BIT);
|
||||||
unsigned const bar_size = pci_config->read(bus, device, function, bar_idx, Device::ACCESS_32BIT);
|
unsigned const bar_size = pci_config->read(bdf, bar_idx, Device::ACCESS_32BIT);
|
||||||
pci_config->write(bus, device, function, bar_idx, bar_value, Device::ACCESS_32BIT);
|
pci_config->write(bdf, bar_idx, bar_value, Device::ACCESS_32BIT);
|
||||||
|
|
||||||
if (!Resource::Bar::mem64(bar_value)) {
|
if (!Resource::Bar::mem64(bar_value)) {
|
||||||
_resource[i] = Resource(bar_value, bar_size);
|
_resource[i] = Resource(bar_value, bar_size);
|
||||||
@ -227,11 +220,11 @@ namespace Platform {
|
|||||||
/* also consume next BAR for MEM64 */
|
/* also consume next BAR for MEM64 */
|
||||||
unsigned const bar2_idx = bar_idx + 4;
|
unsigned const bar2_idx = bar_idx + 4;
|
||||||
unsigned const bar2_value =
|
unsigned const bar2_value =
|
||||||
pci_config->read(bus, device, function, bar2_idx, Device::ACCESS_32BIT);
|
pci_config->read(bdf, bar2_idx, Device::ACCESS_32BIT);
|
||||||
pci_config->write(bus, device, function, bar2_idx, ~0, Device::ACCESS_32BIT);
|
pci_config->write(bdf, bar2_idx, ~0, Device::ACCESS_32BIT);
|
||||||
unsigned const bar2_size =
|
unsigned const bar2_size =
|
||||||
pci_config->read(bus, device, function, bar2_idx, Device::ACCESS_32BIT);
|
pci_config->read(bdf, bar2_idx, Device::ACCESS_32BIT);
|
||||||
pci_config->write(bus, device, function, bar2_idx, bar2_value, Device::ACCESS_32BIT);
|
pci_config->write(bdf, bar2_idx, bar2_value, Device::ACCESS_32BIT);
|
||||||
|
|
||||||
/* combine into first resource and mark second as invalid */
|
/* combine into first resource and mark second as invalid */
|
||||||
_resource[i] = Resource(bar_value, bar_size,
|
_resource[i] = Resource(bar_value, bar_size,
|
||||||
@ -244,24 +237,19 @@ namespace Platform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accessor functions for device location
|
* Accessor function for device location
|
||||||
*/
|
*/
|
||||||
int bus_number() { return _bus; }
|
Pci::Bdf bdf() const { return _bdf; }
|
||||||
int device_number() { return _device; }
|
|
||||||
int function_number() { return _function; }
|
|
||||||
|
|
||||||
void print(Genode::Output &out) const
|
void print(Genode::Output &out) const
|
||||||
{
|
{
|
||||||
using Genode::print;
|
using Genode::print;
|
||||||
using Genode::Hex;
|
using Genode::Hex;
|
||||||
print(out, Hex(_bus, Hex::Prefix::OMIT_PREFIX, Hex::Pad::PAD),
|
print(out, Hex(_bdf.bus(), Hex::Prefix::OMIT_PREFIX, Hex::Pad::PAD),
|
||||||
":", Hex(_device, Hex::Prefix::OMIT_PREFIX, Hex::Pad::PAD),
|
":", Hex(_bdf.device(), Hex::Prefix::OMIT_PREFIX, Hex::Pad::PAD),
|
||||||
".", Hex(_function, Hex::Prefix::OMIT_PREFIX));
|
".", Hex(_bdf.function(), Hex::Prefix::OMIT_PREFIX));
|
||||||
}
|
}
|
||||||
|
|
||||||
Genode::uint16_t bdf () {
|
|
||||||
return (_bus << 8) | (_device << 3) | (_function & 0x7); }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accessor functions for device information
|
* Accessor functions for device information
|
||||||
*/
|
*/
|
||||||
@ -298,8 +286,7 @@ namespace Platform {
|
|||||||
unsigned read(Config_access &pci_config, unsigned char address,
|
unsigned read(Config_access &pci_config, unsigned char address,
|
||||||
Device::Access_size size, bool track = true)
|
Device::Access_size size, bool track = true)
|
||||||
{
|
{
|
||||||
return pci_config.read(_bus, _device, _function, address,
|
return pci_config.read(_bdf, address, size, track);
|
||||||
size, track);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -309,8 +296,7 @@ namespace Platform {
|
|||||||
unsigned long value, Device::Access_size size,
|
unsigned long value, Device::Access_size size,
|
||||||
bool track = true)
|
bool track = true)
|
||||||
{
|
{
|
||||||
pci_config.write(_bus, _device, _function, address, value,
|
pci_config.write(_bdf, address, value, size, track);
|
||||||
size, track);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool reg_in_use(Config_access &pci_config, unsigned char address,
|
bool reg_in_use(Config_access &pci_config, unsigned char address,
|
||||||
@ -346,10 +332,10 @@ namespace Platform {
|
|||||||
:
|
:
|
||||||
_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(Genode::uint32_t bdf)
|
Genode::addr_t lookup_config_space(Pci::Bdf const bdf)
|
||||||
{
|
{
|
||||||
if ((_bdf_start <= bdf) && (bdf <= _bdf_start + _func_count - 1))
|
if ((_bdf_start <= bdf.bdf) && (bdf.bdf <= _bdf_start + _func_count - 1))
|
||||||
return _base + (bdf << 12);
|
return _base + (unsigned(bdf.bdf) << 12);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -79,9 +79,11 @@ class Platform::Rmrr : public Genode::List<Platform::Rmrr>::Element
|
|||||||
Genode::uint8_t func)
|
Genode::uint8_t func)
|
||||||
: _bus(bus), _dev(dev), _func(func) { }
|
: _bus(bus), _dev(dev), _func(func) { }
|
||||||
|
|
||||||
bool match(Genode::uint8_t bus, Genode::uint8_t dev,
|
bool match(Pci::Bdf const bdf)
|
||||||
Genode::uint8_t func) {
|
{
|
||||||
return bus == _bus && dev == _dev && func == _func; }
|
return bdf.bus() == _bus && bdf.device() == _dev &&
|
||||||
|
bdf.function() == _func;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -103,12 +105,8 @@ class Platform::Rmrr : public Genode::List<Platform::Rmrr>::Element
|
|||||||
Genode::Io_mem_dataspace_capability match(Genode::Env &env,
|
Genode::Io_mem_dataspace_capability match(Genode::Env &env,
|
||||||
Device_config config)
|
Device_config config)
|
||||||
{
|
{
|
||||||
Genode::uint8_t bus = config.bus_number();
|
|
||||||
Genode::uint8_t device = config.device_number();
|
|
||||||
Genode::uint8_t function = config.function_number();
|
|
||||||
|
|
||||||
for (Bdf *bdf = _bdf_list.first(); bdf; bdf = bdf->next()) {
|
for (Bdf *bdf = _bdf_list.first(); bdf; bdf = bdf->next()) {
|
||||||
if (!bdf->match(bus, device, function))
|
if (!bdf->match(config.bdf()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (_cap.valid())
|
if (_cap.valid())
|
||||||
@ -183,7 +181,8 @@ class Platform::Pci_buses
|
|||||||
for (; function < Device_config::MAX_FUNCTIONS; function++) {
|
for (; function < Device_config::MAX_FUNCTIONS; function++) {
|
||||||
|
|
||||||
/* read config space */
|
/* read config space */
|
||||||
Device_config config(bus, device, function, config_access);
|
Pci::Bdf const bdf(bus, device, function);
|
||||||
|
Device_config config(bdf, config_access);
|
||||||
|
|
||||||
if (config.valid()) {
|
if (config.valid()) {
|
||||||
*out_device_config = config;
|
*out_device_config = config;
|
||||||
@ -263,7 +262,7 @@ 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(Genode::uint16_t const bdf)
|
Genode::addr_t lookup_config_space(Pci::Bdf const bdf)
|
||||||
{
|
{
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
@ -652,9 +651,9 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
|||||||
|
|
||||||
if (prev) {
|
if (prev) {
|
||||||
Device_config config = prev->device_config();
|
Device_config config = prev->device_config();
|
||||||
bus = config.bus_number();
|
bus = config.bdf().bus();
|
||||||
device = config.device_number();
|
device = config.bdf().device();
|
||||||
function = config.function_number();
|
function = config.bdf().function();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -670,9 +669,9 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
|||||||
return Device_capability();
|
return Device_capability();
|
||||||
|
|
||||||
/* get new bdf values */
|
/* get new bdf values */
|
||||||
bus = config.bus_number();
|
bus = config.bdf().bus();
|
||||||
device = config.device_number();
|
device = config.bdf().device();
|
||||||
function = config.function_number();
|
function = config.bdf().function();
|
||||||
|
|
||||||
/* if filter of driver don't match skip and continue */
|
/* if filter of driver don't match skip and continue */
|
||||||
if ((config.class_code() ^ device_class) & class_mask)
|
if ((config.class_code() ^ device_class) & class_mask)
|
||||||
@ -702,16 +701,12 @@ 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(Device_config::MAX_BUSES * bus +
|
if (bdf_in_use.get(config.bdf().bdf, 1))
|
||||||
Device_config::MAX_DEVICES * device +
|
|
||||||
function, 1))
|
|
||||||
Genode::error("Device ", config,
|
Genode::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(Device_config::MAX_BUSES * bus +
|
bdf_in_use.set(config.bdf().bdf, 1);
|
||||||
Device_config::MAX_DEVICES * device +
|
|
||||||
function, 1);
|
|
||||||
|
|
||||||
return _env.ep().rpc_ep().manage(dev);
|
return _env.ep().rpc_ep().manage(dev);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
@ -733,15 +728,8 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (device->device_config().valid()) {
|
if (device->device_config().valid()) {
|
||||||
unsigned const bus = device->device_config().bus_number();
|
if (bdf_in_use.get(device->device_config().bdf().bdf, 1))
|
||||||
unsigned const dev = device->device_config().device_number();
|
bdf_in_use.clear(device->device_config().bdf().bdf, 1);
|
||||||
unsigned const func = device->device_config().function_number();
|
|
||||||
|
|
||||||
if (bdf_in_use.get(Device_config::MAX_BUSES * bus +
|
|
||||||
Device_config::MAX_DEVICES * dev +
|
|
||||||
func, 1))
|
|
||||||
bdf_in_use.clear(Device_config::MAX_BUSES * bus +
|
|
||||||
Device_config::MAX_DEVICES * dev + func, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_device_list.remove(device);
|
_device_list.remove(device);
|
||||||
@ -763,11 +751,8 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
addr_t const function = device->device_config().bus_number() * 32 * 8 +
|
|
||||||
device->device_config().device_number() * 8 +
|
|
||||||
device->device_config().function_number();
|
|
||||||
addr_t const base_ecam = Dataspace_client(_pciconf.cap()).phys_addr();
|
addr_t const base_ecam = Dataspace_client(_pciconf.cap()).phys_addr();
|
||||||
addr_t const base_offset = 0x1000UL * function;
|
addr_t const base_offset = 0x1000UL * device->device_config().bdf().bdf;
|
||||||
|
|
||||||
if (base_ecam + base_offset != device->config_space())
|
if (base_ecam + base_offset != device->config_space())
|
||||||
throw 1;
|
throw 1;
|
||||||
@ -778,7 +763,8 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
|||||||
_device_pd.attach_dma_mem(rmrr_cap);
|
_device_pd.attach_dma_mem(rmrr_cap);
|
||||||
}
|
}
|
||||||
|
|
||||||
_device_pd.assign_pci(_pciconf.cap(), base_offset, device->device_config().bdf());
|
_device_pd.assign_pci(_pciconf.cap(), base_offset,
|
||||||
|
device->device_config().bdf().bdf);
|
||||||
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
Genode::error("assignment to device pd or of RMRR region failed");
|
Genode::error("assignment to device pd or of RMRR region failed");
|
||||||
@ -857,8 +843,12 @@ class Platform::Root : public Genode::Root_component<Session_component>
|
|||||||
Session_component::add_config_space(bdf_start, func_count,
|
Session_component::add_config_space(bdf_start, func_count,
|
||||||
base, _heap);
|
base, _heap);
|
||||||
|
|
||||||
Device_config const bdf_first(bdf_start);
|
Pci::Bdf const bdf_s(bdf_start);
|
||||||
Device_config const bdf_last(bdf_start + func_count - 1);
|
Pci::Bdf const bdf_l(bdf_start + func_count - 1);
|
||||||
|
|
||||||
|
Device_config const bdf_first(bdf_s);
|
||||||
|
Device_config const bdf_last(bdf_l);
|
||||||
|
|
||||||
addr_t const memory_size = 0x1000UL * func_count;
|
addr_t const memory_size = 0x1000UL * func_count;
|
||||||
|
|
||||||
/* Simplification: Only consider first config space and
|
/* Simplification: Only consider first config space and
|
||||||
@ -937,8 +927,8 @@ class Platform::Root : public Genode::Root_component<Session_component>
|
|||||||
path.attribute("dev") .value(dev);
|
path.attribute("dev") .value(dev);
|
||||||
path.attribute("func").value(func);
|
path.attribute("func").value(func);
|
||||||
|
|
||||||
Device_config bridge(bus, dev, func,
|
Pci::Bdf const bdf(bus, dev, func);
|
||||||
&config_access);
|
Device_config bridge(bdf, &config_access);
|
||||||
if (bridge.pci_bridge())
|
if (bridge.pci_bridge())
|
||||||
/* PCI bridge spec 3.2.5.3, 3.2.5.4 */
|
/* PCI bridge spec 3.2.5.3, 3.2.5.4 */
|
||||||
bus = bridge.read(config_access, 0x19,
|
bus = bridge.read(config_access, 0x19,
|
||||||
@ -1062,7 +1052,7 @@ class Platform::Root : public Genode::Root_component<Session_component>
|
|||||||
}
|
}
|
||||||
|
|
||||||
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(Platform::Bridge::root_bridge_bdf);
|
Device_config config(Pci::Bdf(Platform::Bridge::root_bridge_bdf));
|
||||||
Genode::log("Root bridge: ", config);
|
Genode::log("Root bridge: ", config);
|
||||||
} else
|
} else
|
||||||
Genode::warning("Root bridge: unknown");
|
Genode::warning("Root bridge: unknown");
|
||||||
@ -1087,9 +1077,9 @@ class Platform::Root : public Genode::Root_component<Session_component>
|
|||||||
&config_access))
|
&config_access))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bus = config.bus_number();
|
bus = config.bdf().bus();
|
||||||
device = config.device_number();
|
device = config.bdf().device();
|
||||||
function = config.function_number();
|
function = config.bdf().function();
|
||||||
|
|
||||||
using Genode::String;
|
using Genode::String;
|
||||||
using Genode::Hex;
|
using Genode::Hex;
|
||||||
|
@ -45,7 +45,7 @@ void Platform::Pci_buses::scan_bus(Config_access &config_access,
|
|||||||
for (int fun = 0; fun < Device_config::MAX_FUNCTIONS; ++fun) {
|
for (int fun = 0; fun < Device_config::MAX_FUNCTIONS; ++fun) {
|
||||||
|
|
||||||
/* read config space */
|
/* read config space */
|
||||||
Device_config config(bus, dev, fun, &config_access);
|
Device_config config(Pci::Bdf(bus, dev, fun), &config_access);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Switch off PCI bus master DMA for some classes of devices,
|
* Switch off PCI bus master DMA for some classes of devices,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user