1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-16 00:00:02 +01:00
VILLASnode/common/include/villas/kernel/pci.hpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

141 lines
2.9 KiB
C++
Raw Normal View History

2020-06-14 21:52:29 +02:00
/** Linux PCI helpers
*
* @file
* @author Steffen Vogel <post@steffenvogel.de>
2022-03-15 09:05:42 -04:00
* @copyright 2014-2022, Institute for Automation of Complex Power Systems, EONERC
2022-05-19 17:40:10 +02:00
* @license Apache License 2.0
2020-06-14 21:52:29 +02:00
*********************************************************************************/
#pragma once
#include <list>
#include <fstream>
2020-06-14 21:52:29 +02:00
#include <cstddef>
#include <cstdint>
#include <villas/log.hpp>
2020-06-14 21:52:29 +02:00
namespace villas {
namespace kernel {
namespace pci {
#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f)
#define PCI_FUNC(devfn) ((devfn) & 0x07)
class Id {
public:
Id(const std::string &str);
Id(int vid = 0, int did = 0, int cc = 0) :
vendor(vid),
device(did),
class_code(cc)
{ }
bool operator==(const Id &i);
2020-06-14 21:52:29 +02:00
unsigned int vendor;
unsigned int device;
unsigned int class_code;
2020-06-14 21:52:29 +02:00
};
class Slot {
public:
Slot(const std::string &str);
Slot(int dom = 0, int b = 0, int dev = 0, int fcn = 0) :
domain(dom),
bus(b),
device(dev),
function(fcn)
{ }
bool operator==(const Slot &s);
2020-06-14 21:52:29 +02:00
unsigned int domain;
unsigned int bus;
unsigned int device;
unsigned int function;
2020-06-14 21:52:29 +02:00
};
struct Region {
int num;
uintptr_t start;
uintptr_t end;
unsigned long long flags;
};
class Device {
public:
Device(Id i, Slot s) :
id(i),
slot(s),
log(logging.get("kernel:pci"))
2020-06-14 21:52:29 +02:00
{ }
2020-06-15 21:05:51 +02:00
Device(Id i) :
id(i),
log(logging.get("kernel:pci"))
2020-06-15 21:05:51 +02:00
{ }
2020-06-14 21:52:29 +02:00
2020-06-15 21:05:51 +02:00
Device(Slot s) :
slot(s),
log(logging.get("kernel:pci"))
2020-06-15 21:05:51 +02:00
{ }
2020-06-14 21:52:29 +02:00
bool
2020-06-15 21:05:51 +02:00
operator==(const Device &other);
2020-06-14 21:52:29 +02:00
// Get currently loaded driver for device.
std::string getDriver() const;
2020-06-14 21:52:29 +02:00
// Bind a new LKM to the PCI device.
bool attachDriver(const std::string &driver) const;
2020-06-14 21:52:29 +02:00
// Return the IOMMU group of this PCI device or -1 if the device is not in a group.
int getIommuGroup() const;
2020-06-14 21:52:29 +02:00
std::list<Region> getRegions() const;
2020-06-14 21:52:29 +02:00
// Write 32-bit BAR value from to the PCI configuration space
void writeBar(uint32_t addr, unsigned bar = 0);
// If BAR values in config space and in the kernel do not match, rewrite
// the BAR value of the kernel to PCIe config space.
void rewriteBar(unsigned bar = 0);
// Read 32-bit BAR value from the PCI configuration space.
uint32_t readBar(unsigned bar = 0) const;
// Read 32-bit BAR value from the devices resource file. This is what the kernel
// thinks the BAR should be.
uint32_t readHostBar(unsigned bar = 0) const;
2020-06-14 21:52:29 +02:00
Id id;
Slot slot;
private:
villas::Logger log;
protected:
std::fstream openSysFs(const std::string &subPath, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) const;
2020-06-14 21:52:29 +02:00
};
2020-06-15 21:05:51 +02:00
class DeviceList : public std::list<std::shared_ptr<Device>> {
2020-06-14 21:52:29 +02:00
public:
// Initialize Linux PCI handle.
//
// This search for all available PCI devices under /sys/bus/pci
2020-06-14 21:52:29 +02:00
DeviceList();
DeviceList::value_type lookupDevice(const Slot &s);
2020-06-15 21:05:51 +02:00
DeviceList::value_type lookupDevice(const Id &i);
2020-06-14 21:52:29 +02:00
DeviceList::value_type lookupDevice(const Device &f);
2020-06-14 21:52:29 +02:00
};
} // namespace pci
} // namespace kernel
} // namespace villas