mirror of
https://github.com/mmueller41/genode.git
synced 2026-01-21 12:32:56 +01:00
platform_drv: provide Virtio PCI information
Ref genodelabs/genode#4578
This commit is contained in:
committed by
Christian Helmuth
parent
de0c339e0b
commit
fdba7259ab
@@ -228,7 +228,7 @@ class Driver::Device : private List_model<Device>::Element
|
|||||||
{
|
{
|
||||||
unsigned idx = 0;
|
unsigned idx = 0;
|
||||||
_io_mem_list.for_each([&] (Io_mem const & iomem) {
|
_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
|
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);
|
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});
|
session.ram_quota_guard().withdraw(Ram_quota{Io_mem_session::RAM_QUOTA});
|
||||||
_ram_quota += Io_mem_session::RAM_QUOTA;
|
_ram_quota += Io_mem_session::RAM_QUOTA;
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include <pci_uhci.h>
|
#include <pci_uhci.h>
|
||||||
#include <pci_intel_graphics.h>
|
#include <pci_intel_graphics.h>
|
||||||
#include <pci_hd_audio.h>
|
#include <pci_hd_audio.h>
|
||||||
|
#include <pci_virtio.h>
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
using namespace Pci;
|
using namespace Pci;
|
||||||
@@ -51,7 +52,8 @@ struct Config_helper
|
|||||||
Config::Command::Bus_master_enable::set(cmd, 1);
|
Config::Command::Bus_master_enable::set(cmd, 1);
|
||||||
|
|
||||||
/* enable memory space when I/O mem is defined */
|
/* 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); });
|
Config::Command::Memory_space_enable::set(cmd, 1); });
|
||||||
|
|
||||||
/* enable i/o space when I/O ports are defined */
|
/* 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,
|
Device_model & model,
|
||||||
Xml_generator & xml)
|
Xml_generator & xml)
|
||||||
{
|
{
|
||||||
dev.for_pci_config([&] (Device::Pci_config const cfg) {
|
dev.for_pci_config([&] (Device::Pci_config const cfg)
|
||||||
Driver::pci_intel_graphics_info(cfg, env, model, xml); });
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user