mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-16 07:27:35 +00:00
platform_drv: export Intel graphics PCI infos
Provide additional PCI register information inside the pci-config part of the devices ROM for clients able to access an Intel graphic card, namely the GMCH control register content, which contains for instance the GTT size and stolen memory size. Ref genodelabs/genode#4578
This commit is contained in:
parent
9dfc2caa11
commit
8255053242
@ -24,7 +24,7 @@ class Driver::Common : Device_reporter
|
||||
Attached_rom_dataspace _devices_rom { _env, _rom_name.string() };
|
||||
Heap _heap { _env.ram(), _env.rm() };
|
||||
Sliced_heap _sliced_heap { _env.ram(), _env.rm() };
|
||||
Device_model _devices { _heap, *this };
|
||||
Device_model _devices { _env, _heap, *this };
|
||||
Signal_handler<Common> _dev_handler { _env.ep(), *this,
|
||||
&Common::_handle_devices };
|
||||
Driver::Root _root;
|
||||
|
@ -79,7 +79,7 @@ void Driver::Device::acquire(Session_component & sc)
|
||||
}
|
||||
});
|
||||
|
||||
pci_enable(sc.env(), sc.device_pd(), *this);
|
||||
pci_enable(_env, sc.device_pd(), *this);
|
||||
sc.update_devices_rom();
|
||||
_model.device_status_changed();
|
||||
}
|
||||
@ -90,7 +90,7 @@ void Driver::Device::release(Session_component & sc)
|
||||
if (!(_owner == sc))
|
||||
return;
|
||||
|
||||
pci_disable(sc.env(), *this);
|
||||
pci_disable(_env, *this);
|
||||
|
||||
_reset_domain_list.for_each([&] (Reset_domain & r)
|
||||
{
|
||||
@ -171,14 +171,15 @@ void Driver::Device::generate(Xml_generator & xml, bool info) const
|
||||
xml.attribute("revision", String<16>(Hex(pci.revision)));
|
||||
xml.attribute("sub_vendor_id", String<16>(Hex(pci.sub_vendor_id)));
|
||||
xml.attribute("sub_device_id", String<16>(Hex(pci.sub_device_id)));
|
||||
pci_device_specific_info(*this, _env, _model, xml);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Driver::Device::Device(Device_model & model, Name name, Type type)
|
||||
: _model(model), _name(name), _type(type) { }
|
||||
Driver::Device::Device(Env & env, Device_model & model, Name name, Type type)
|
||||
: _env(env), _model(model), _name(name), _type(type) { }
|
||||
|
||||
|
||||
Driver::Device::~Device()
|
||||
|
@ -197,7 +197,7 @@ class Driver::Device : private List_model<Device>::Element
|
||||
bridge(bridge) {}
|
||||
};
|
||||
|
||||
Device(Device_model & model, Name name, Type type);
|
||||
Device(Env & env, Device_model & model, Name name, Type type);
|
||||
virtual ~Device();
|
||||
|
||||
Name name() const;
|
||||
@ -253,6 +253,7 @@ class Driver::Device : private List_model<Device>::Element
|
||||
friend class List_model<Device>;
|
||||
friend class List<Device>;
|
||||
|
||||
Env & _env;
|
||||
Device_model & _model;
|
||||
Name const _name;
|
||||
Type const _type;
|
||||
@ -287,6 +288,7 @@ class Driver::Device_model :
|
||||
{
|
||||
private:
|
||||
|
||||
Env & _env;
|
||||
Heap & _heap;
|
||||
Device_reporter & _reporter;
|
||||
List_model<Device> _model { };
|
||||
@ -300,9 +302,10 @@ class Driver::Device_model :
|
||||
void update(Xml_node const & node);
|
||||
void device_status_changed();
|
||||
|
||||
Device_model(Heap & heap,
|
||||
Device_model(Env & env,
|
||||
Heap & heap,
|
||||
Device_reporter & reporter)
|
||||
: _heap(heap), _reporter(reporter) { }
|
||||
: _env(env), _heap(heap), _reporter(reporter) { }
|
||||
|
||||
~Device_model() {
|
||||
_model.destroy_all_elements(*this); }
|
||||
|
@ -49,7 +49,7 @@ Device_component::io_mem(unsigned idx, Range &range, Cache cache)
|
||||
return;
|
||||
|
||||
if (!iomem.io_mem.constructed())
|
||||
iomem.io_mem.construct(_session.env(),
|
||||
iomem.io_mem.construct(_env,
|
||||
iomem.range.start,
|
||||
iomem.range.size,
|
||||
cache == WRITE_COMBINED);
|
||||
@ -79,11 +79,11 @@ Genode::Irq_session_capability Device_component::irq(unsigned idx)
|
||||
else
|
||||
error("MSI(-x) detected for device without pci-config!");
|
||||
}
|
||||
irq.irq.construct(_session.env(), irq.number, irq.mode, irq.polarity,
|
||||
irq.irq.construct(_env, irq.number, irq.mode, irq.polarity,
|
||||
pci_cfg_addr);
|
||||
Irq_session::Info info = irq.irq->info();
|
||||
if (info.type == Irq_session::Info::MSI)
|
||||
pci_msi_enable(_session.env(), pci_cfg_addr, info);
|
||||
pci_msi_enable(_env, pci_cfg_addr, info);
|
||||
}
|
||||
|
||||
cap = irq.irq->cap();
|
||||
@ -103,7 +103,7 @@ Genode::Io_port_session_capability Device_component::io_port_range(unsigned idx)
|
||||
return;
|
||||
|
||||
if (!ipr.io_port_range.constructed())
|
||||
ipr.io_port_range.construct(_session.env(), ipr.range.addr,
|
||||
ipr.io_port_range.construct(_env, ipr.range.addr,
|
||||
ipr.range.size);
|
||||
|
||||
cap = ipr.io_port_range->cap();
|
||||
@ -114,9 +114,14 @@ Genode::Io_port_session_capability Device_component::io_port_range(unsigned idx)
|
||||
|
||||
|
||||
Device_component::Device_component(Registry<Device_component> & registry,
|
||||
Env & env,
|
||||
Driver::Session_component & session,
|
||||
Driver::Device & device)
|
||||
: _session(session), _device(device.name()), _reg_elem(registry, *this)
|
||||
:
|
||||
_env(env),
|
||||
_session(session),
|
||||
_device(device.name()),
|
||||
_reg_elem(registry, *this)
|
||||
{
|
||||
session.cap_quota_guard().withdraw(Cap_quota{1});
|
||||
_cap_quota += 1;
|
||||
|
@ -95,6 +95,7 @@ class Driver::Device_component : public Rpc_object<Platform::Device_interface,
|
||||
};
|
||||
|
||||
Device_component(Registry<Device_component> & registry,
|
||||
Env & env,
|
||||
Session_component & session,
|
||||
Driver::Device & device);
|
||||
~Device_component();
|
||||
@ -113,6 +114,7 @@ class Driver::Device_component : public Rpc_object<Platform::Device_interface,
|
||||
|
||||
private:
|
||||
|
||||
Env & _env;
|
||||
Session_component & _session;
|
||||
Driver::Device::Name const _device;
|
||||
size_t _cap_quota { 0 };
|
||||
|
@ -66,7 +66,7 @@ Device & Device_model::create_element(Genode::Xml_node node)
|
||||
{
|
||||
Device::Name name = node.attribute_value("name", Device::Name());
|
||||
Device::Type type = node.attribute_value("type", Device::Type());
|
||||
return *(new (_heap) Device(*this, name, type));
|
||||
return *(new (_heap) Device(_env, *this, name, type));
|
||||
}
|
||||
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <device_pd.h>
|
||||
#include <pci.h>
|
||||
#include <pci_uhci.h>
|
||||
#include <pci_intel_graphics.h>
|
||||
|
||||
using namespace Genode;
|
||||
using namespace Pci;
|
||||
@ -172,3 +173,13 @@ bool Driver::pci_device_matches(Session_policy const & policy,
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void Driver::pci_device_specific_info(Device const & dev,
|
||||
Env & env,
|
||||
Device_model & model,
|
||||
Xml_generator & xml)
|
||||
{
|
||||
dev.for_pci_config([&] (Device::Pci_config const cfg) {
|
||||
Driver::pci_intel_graphics_info(cfg, env, model, xml); });
|
||||
}
|
||||
|
@ -28,6 +28,10 @@ namespace Driver {
|
||||
Genode::Irq_session::Info const info);
|
||||
bool pci_device_matches(Genode::Session_policy const & policy,
|
||||
Device const & dev);
|
||||
void pci_device_specific_info(Device const & dev,
|
||||
Env & env,
|
||||
Device_model & model,
|
||||
Xml_generator & xml);
|
||||
}
|
||||
|
||||
#endif /* _SRC__DRIVERS__PLATFORM__PCI_H_ */
|
||||
|
124
repos/os/src/drivers/platform/pci_intel_graphics.h
Normal file
124
repos/os/src/drivers/platform/pci_intel_graphics.h
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* \brief Platform driver - PCI intel graphics utilities
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2022-06-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#include <util/mmio.h>
|
||||
#include <pci/config.h>
|
||||
#include <device.h>
|
||||
|
||||
namespace Driver {
|
||||
void pci_intel_graphics_info(Device::Pci_config cfg,
|
||||
Env & env,
|
||||
Device_model & model,
|
||||
Xml_generator & xml);
|
||||
}
|
||||
|
||||
|
||||
static inline unsigned pci_intel_graphics_generation(Pci::device_t id)
|
||||
{
|
||||
struct Device_gen {
|
||||
Pci::device_t id;
|
||||
unsigned gen;
|
||||
};
|
||||
|
||||
static Device_gen intel_gpu_generations[] = {
|
||||
{ 0x7121, 1 }, { 0x7123, 1 }, { 0x7125, 1 }, { 0x1132, 1 },
|
||||
{ 0x3577, 2 }, { 0x2562, 2 }, { 0x3582, 2 }, { 0x358e, 2 },
|
||||
{ 0x2572, 2 }, { 0x2582, 3 }, { 0x258a, 3 }, { 0x2592, 3 },
|
||||
{ 0x2772, 3 }, { 0x27a2, 3 }, { 0x27ae, 3 }, { 0x29b2, 3 },
|
||||
{ 0x29c2, 3 }, { 0x29d2, 3 }, { 0xa001, 3 }, { 0xa011, 3 },
|
||||
{ 0x2972, 4 }, { 0x2982, 4 }, { 0x2992, 4 }, { 0x29a2, 4 },
|
||||
{ 0x2a02, 4 }, { 0x2a12, 4 }, { 0x2a42, 4 }, { 0x2e02, 4 },
|
||||
{ 0x2e12, 4 }, { 0x2e22, 4 }, { 0x2e32, 4 }, { 0x2e42, 4 },
|
||||
{ 0x2e92, 4 }, { 0x0042, 5 }, { 0x0046, 5 }, { 0x0102, 6 },
|
||||
{ 0x010a, 6 }, { 0x0112, 6 }, { 0x0122, 6 }, { 0x0106, 6 },
|
||||
{ 0x0116, 6 }, { 0x0126, 6 }, { 0x0156, 6 }, { 0x0166, 6 },
|
||||
{ 0x0152, 7 }, { 0x015a, 7 }, { 0x0162, 7 }, { 0x016a, 7 },
|
||||
{ 0x0a02, 7 }, { 0x0a06, 7 }, { 0x0a0a, 7 }, { 0x0a0b, 7 },
|
||||
{ 0x0a0e, 7 }, { 0x0402, 7 }, { 0x0406, 7 }, { 0x040a, 7 },
|
||||
{ 0x040b, 7 }, { 0x040e, 7 }, { 0x0c02, 7 }, { 0x0c06, 7 },
|
||||
{ 0x0c0a, 7 }, { 0x0c0b, 7 }, { 0x0c0e, 7 }, { 0x0d02, 7 },
|
||||
{ 0x0d06, 7 }, { 0x0d0a, 7 }, { 0x0d0b, 7 }, { 0x0d0e, 7 },
|
||||
{ 0x0a12, 7 }, { 0x0a16, 7 }, { 0x0a1a, 7 }, { 0x0a1b, 7 },
|
||||
{ 0x0a1e, 7 }, { 0x0412, 7 }, { 0x0416, 7 }, { 0x041a, 7 },
|
||||
{ 0x041b, 7 }, { 0x041e, 7 }, { 0x0c12, 7 }, { 0x0c16, 7 },
|
||||
{ 0x0c1a, 7 }, { 0x0c1b, 7 }, { 0x0c1e, 7 }, { 0x0d12, 7 },
|
||||
{ 0x0d16, 7 }, { 0x0d1a, 7 }, { 0x0d1b, 7 }, { 0x0d1e, 7 },
|
||||
{ 0x0a22, 7 }, { 0x0a26, 7 }, { 0x0a2a, 7 }, { 0x0a2b, 7 },
|
||||
{ 0x0a2e, 7 }, { 0x0422, 7 }, { 0x0426, 7 }, { 0x042a, 7 },
|
||||
{ 0x042b, 7 }, { 0x042e, 7 }, { 0x0c22, 7 }, { 0x0c26, 7 },
|
||||
{ 0x0c2a, 7 }, { 0x0c2b, 7 }, { 0x0c2e, 7 }, { 0x0d22, 7 },
|
||||
{ 0x0d26, 7 }, { 0x0d2a, 7 }, { 0x0d2b, 7 }, { 0x0d2e, 7 },
|
||||
{ 0x0f30, 7 }, { 0x0f31, 7 }, { 0x0f32, 7 }, { 0x0f33, 7 },
|
||||
};
|
||||
for (unsigned i = 0;
|
||||
i < (sizeof(intel_gpu_generations)/(sizeof(Device_gen)));
|
||||
i++) {
|
||||
if (id == intel_gpu_generations[i].id)
|
||||
return intel_gpu_generations[i].gen;
|
||||
};
|
||||
|
||||
/*
|
||||
* If we do not find something in the array, we assume its
|
||||
* generation 8 or higher
|
||||
*/
|
||||
return 8;
|
||||
};
|
||||
|
||||
|
||||
void Driver::pci_intel_graphics_info(Device::Pci_config cfg,
|
||||
Env & env,
|
||||
Device_model & model,
|
||||
Xml_generator & xml)
|
||||
{
|
||||
enum {
|
||||
GPU_CLASS_MASK = 0xff0000,
|
||||
GPU_CLASS_ID = 0x030000,
|
||||
VENDOR_INTEL = 0x8086
|
||||
};
|
||||
|
||||
if (((cfg.class_code & GPU_CLASS_MASK) != GPU_CLASS_ID) ||
|
||||
(cfg.vendor_id != VENDOR_INTEL))
|
||||
return;
|
||||
|
||||
/* PCI configuration registers of host bridge */
|
||||
struct Host_bridge : Mmio
|
||||
{
|
||||
struct Gen_old_gmch_control : Register<0x52, 16> {};
|
||||
struct Gen_6_7_gmch_control : Register<0x50, 16> {};
|
||||
struct Gen_gmch_control : Register<0x52, 16> {};
|
||||
|
||||
using Mmio::Mmio;
|
||||
};
|
||||
|
||||
/* find host bridge */
|
||||
model.for_each([&] (Device const & dev) {
|
||||
dev.for_pci_config([&] (Device::Pci_config const cfg) {
|
||||
if (cfg.bus_num || cfg.dev_num || cfg.func_num)
|
||||
return;
|
||||
|
||||
Attached_io_mem_dataspace io_mem(env, cfg.addr, 0x1000);
|
||||
Host_bridge config((addr_t)io_mem.local_addr<void>());
|
||||
unsigned gen = pci_intel_graphics_generation(cfg.device_id);
|
||||
uint16_t gmch = 0;
|
||||
|
||||
if (gen < 6)
|
||||
gmch = config.read<Host_bridge::Gen_old_gmch_control>();
|
||||
else if (gen < 8)
|
||||
gmch = config.read<Host_bridge::Gen_6_7_gmch_control>();
|
||||
else
|
||||
gmch = config.read<Host_bridge::Gen_gmch_control>();
|
||||
|
||||
xml.attribute("intel_gmch_control", String<16>(Hex(gmch)));
|
||||
});
|
||||
});
|
||||
}
|
@ -24,7 +24,7 @@ Genode::Capability<Platform::Device_interface>
|
||||
Session_component::_acquire(Device & device)
|
||||
{
|
||||
Device_component * dc = new (heap())
|
||||
Device_component(_device_registry, *this, device);
|
||||
Device_component(_device_registry, _env, *this, device);
|
||||
device.acquire(*this);
|
||||
return _env.ep().rpc_ep().manage(dc);
|
||||
};
|
||||
@ -112,9 +112,6 @@ void Session_component::produce_xml(Xml_generator &xml)
|
||||
}
|
||||
|
||||
|
||||
Genode::Env & Session_component::env() { return _env; }
|
||||
|
||||
|
||||
Genode::Heap & Session_component::heap() { return _md_alloc; }
|
||||
|
||||
|
||||
|
@ -56,7 +56,6 @@ class Driver::Session_component
|
||||
|
||||
~Session_component();
|
||||
|
||||
Env & env();
|
||||
Heap & heap();
|
||||
Device_pd & device_pd();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user