mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-21 02:01:38 +00:00
platform_drv: provide Virtio PCI information
Ref genodelabs/genode#4578
This commit is contained in:
parent
de0c339e0b
commit
fdba7259ab
@ -228,7 +228,7 @@ class Driver::Device : private List_model<Device>::Element
|
||||
{
|
||||
unsigned idx = 0;
|
||||
_io_mem_list.for_each([&] (Io_mem const & iomem) {
|
||||
fn(idx++, iomem.range); });
|
||||
fn(idx++, iomem.range, iomem.bar); });
|
||||
}
|
||||
|
||||
template <typename FN> void for_each_io_port_range(FN const & fn) const
|
||||
|
@ -159,7 +159,7 @@ Device_component::Device_component(Registry<Device_component> & registry,
|
||||
new (session.heap()) Irq(_irq_registry, idx, nr, type, polarity, mode);
|
||||
});
|
||||
|
||||
device.for_each_io_mem([&] (unsigned idx, Range range)
|
||||
device.for_each_io_mem([&] (unsigned idx, Range range, Device::Pci_bar)
|
||||
{
|
||||
session.ram_quota_guard().withdraw(Ram_quota{Io_mem_session::RAM_QUOTA});
|
||||
_ram_quota += Io_mem_session::RAM_QUOTA;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <pci_uhci.h>
|
||||
#include <pci_intel_graphics.h>
|
||||
#include <pci_hd_audio.h>
|
||||
#include <pci_virtio.h>
|
||||
|
||||
using namespace Genode;
|
||||
using namespace Pci;
|
||||
@ -51,7 +52,8 @@ struct Config_helper
|
||||
Config::Command::Bus_master_enable::set(cmd, 1);
|
||||
|
||||
/* enable memory space when I/O mem is defined */
|
||||
_dev.for_each_io_mem([&] (unsigned, Driver::Device::Io_mem::Range) {
|
||||
_dev.for_each_io_mem([&] (unsigned, Driver::Device::Io_mem::Range,
|
||||
Driver::Device::Pci_bar) {
|
||||
Config::Command::Memory_space_enable::set(cmd, 1); });
|
||||
|
||||
/* enable i/o space when I/O ports are defined */
|
||||
@ -182,6 +184,9 @@ void Driver::pci_device_specific_info(Device const & dev,
|
||||
Device_model & model,
|
||||
Xml_generator & xml)
|
||||
{
|
||||
dev.for_pci_config([&] (Device::Pci_config const cfg) {
|
||||
Driver::pci_intel_graphics_info(cfg, env, model, xml); });
|
||||
dev.for_pci_config([&] (Device::Pci_config const cfg)
|
||||
{
|
||||
Driver::pci_intel_graphics_info(cfg, env, model, xml);
|
||||
Driver::pci_virtio_info(dev, cfg, env, xml);
|
||||
});
|
||||
}
|
||||
|
119
repos/os/src/drivers/platform/pci_virtio.h
Normal file
119
repos/os/src/drivers/platform/pci_virtio.h
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* \brief Platform driver - PCI Virtio utilities
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2022-09-19
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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_virtio_info(Device const & dev,
|
||||
Device::Pci_config cfg,
|
||||
Env & env,
|
||||
Xml_generator & xml);
|
||||
}
|
||||
|
||||
|
||||
void Driver::pci_virtio_info(Device const & dev,
|
||||
Device::Pci_config cfg,
|
||||
Env & env,
|
||||
Xml_generator & xml)
|
||||
{
|
||||
enum { VENDOR_RED_HAT = 0x1af4 };
|
||||
|
||||
if (cfg.vendor_id != VENDOR_RED_HAT)
|
||||
return;
|
||||
|
||||
struct Virtio : Pci::Config
|
||||
{
|
||||
struct Capability : Pci::Config::Pci_capability
|
||||
{
|
||||
enum { COMMON = 1, NOTIFY = 2, ISR = 3, DEVICE = 4 };
|
||||
|
||||
struct Type : Register<0x3, 8> {};
|
||||
struct Bar : Register<0x4, 8> {};
|
||||
struct Offset : Register<0x8, 32> {};
|
||||
struct Length : Register<0xc, 32> {};
|
||||
struct Offset_factor : Register<0x10, 32> {};
|
||||
|
||||
using Pci::Config::Pci_capability::Pci_capability;
|
||||
|
||||
bool valid()
|
||||
{
|
||||
switch (read<Type>()) {
|
||||
case COMMON:
|
||||
case NOTIFY:
|
||||
case ISR:
|
||||
case DEVICE:
|
||||
return true;
|
||||
};
|
||||
return false;
|
||||
}
|
||||
|
||||
String<16> name()
|
||||
{
|
||||
switch (read<Type>()) {
|
||||
case COMMON: return "common";
|
||||
case NOTIFY: return "notify";
|
||||
case ISR: return "irq_status";
|
||||
case DEVICE: return "device";
|
||||
};
|
||||
return "unknown";
|
||||
}
|
||||
};
|
||||
|
||||
using Pci::Config::Config;
|
||||
|
||||
void capability(Capability & cap,
|
||||
Driver::Device const & dev,
|
||||
Xml_generator & xml)
|
||||
{
|
||||
unsigned idx = ~0U;
|
||||
dev.for_each_io_mem([&] (unsigned i,
|
||||
Driver::Device::Io_mem::Range,
|
||||
Driver::Device::Pci_bar bar) {
|
||||
if (bar.number == cap.read<Capability::Bar>()) idx = i; });
|
||||
|
||||
xml.node("virtio_range", [&] () {
|
||||
xml.attribute("type", cap.name());
|
||||
xml.attribute("index", idx);
|
||||
xml.attribute("offset", cap.read<Capability::Offset>());
|
||||
xml.attribute("size", cap.read<Capability::Length>());
|
||||
if (cap.read<Capability::Type>() == Capability::NOTIFY)
|
||||
xml.attribute("factor",
|
||||
cap.read<Capability::Offset_factor>());
|
||||
});
|
||||
}
|
||||
|
||||
void for_each_capability(Driver::Device const & dev,
|
||||
Xml_generator & xml)
|
||||
{
|
||||
if (!read<Status::Capabilities>())
|
||||
return;
|
||||
|
||||
uint16_t off = read<Capability_pointer>();
|
||||
while (off) {
|
||||
Capability cap(base() + off);
|
||||
if (cap.read<Pci_capability::Id>() ==
|
||||
Pci_capability::Id::VENDOR &&
|
||||
cap.valid())
|
||||
capability(cap, dev, xml);
|
||||
off = cap.read<Pci_capability::Pointer>();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Attached_io_mem_dataspace io_mem(env, cfg.addr, 0x1000);
|
||||
Virtio config((addr_t)io_mem.local_addr<void>());
|
||||
config.for_each_capability(dev, xml);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user