lx_emul: add PCI config space handling

Ref genodelabs/genode#4411
This commit is contained in:
Josef Söntgen 2022-02-01 15:00:05 +01:00 committed by Norman Feske
parent c851b189c5
commit 77ab7bf68b
3 changed files with 113 additions and 0 deletions

View File

@ -0,0 +1,28 @@
/*
* \brief Lx_emul support for accessing PCI(e) config space
* \author Josef Soentgen
* \date 2022-01-18
*/
/*
* Copyright (C) 2022 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#ifndef _LX_EMUL__PCI_CONFIG_SPACE_H_
#define _LX_EMUL__PCI_CONFIG_SPACE_H_
#ifdef __cplusplus
extern "C" {
#endif
int lx_emul_pci_read_config(unsigned bus, unsigned devfn, unsigned reg, unsigned len, unsigned *val);
int lx_emul_pci_write_config(unsigned bus, unsigned devfn, unsigned reg, unsigned len, unsigned val);
#ifdef __cplusplus
}
#endif
#endif /* _LX_EMUL__PCI_CONFIG_SPACE_H_ */

View File

@ -122,6 +122,9 @@ class Lx_kit::Device : List<Device>::Element
bool irq_unmask(unsigned irq);
void irq_mask(unsigned irq);
void irq_ack(unsigned irq);
bool read_config(unsigned reg, unsigned len, unsigned *val);
bool write_config(unsigned reg, unsigned len, unsigned val);
};

View File

@ -0,0 +1,82 @@
/*
* \brief Lx_emul backend for accessing PCI(e) config space
* \author Josef Soentgen
* \date 2022-01-18
*/
/*
* Copyright (C) 2022 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <lx_kit/env.h>
#include <lx_emul/pci_config_space.h>
using Device_name = Genode::String<16>;
template <typename T, typename... TAIL>
static Device_name to_string(T const &arg, TAIL &&... args)
{
return Device_name(arg, args...);
}
static Device_name assemble(unsigned bus, unsigned devfn)
{
using namespace Genode;
return to_string("pci-",
Hex(bus, Hex::OMIT_PREFIX), ":",
Hex((devfn >> 3) & 0x1fu, Hex::OMIT_PREFIX), ".",
Hex(devfn & 0x7u, Hex::OMIT_PREFIX));
}
int lx_emul_pci_read_config(unsigned bus, unsigned devfn,
unsigned reg, unsigned len, unsigned *val)
{
using namespace Lx_kit;
using namespace Genode;
Device_name name = assemble(bus, devfn);
bool result = false;
bool matched = false;
env().devices.for_each([&] (Device & d) {
matched = name == d.name();
if (matched && val)
result = d.read_config(reg, len, val);
});
if (!result && matched)
error("could not read config space register ", Hex(reg));
return result ? 0 : -1;
}
int lx_emul_pci_write_config(unsigned bus, unsigned devfn,
unsigned reg, unsigned len, unsigned val)
{
using namespace Lx_kit;
using namespace Genode;
Device_name name = assemble(bus, devfn);
bool result = false;
bool matched = false;
env().devices.for_each ([&] (Device & d) {
matched = name == d.name();
if (matched)
result = d.write_config(reg, len, val);
});
if (!result && matched)
error("could not write config space register ", Hex(reg),
" with ", Hex(val));
return result ? 0 : -1;
}