2#ifndef PEDIGREE_PCI_FUNCTION_STATE_H
3#define PEDIGREE_PCI_FUNCTION_STATE_H
4#include "pedigree/kernel/processor/types.h"
6namespace PciFunctionState {
10 uint8_t interruptLine = 0, interruptPin = 0;
11 uint8_t pm = 0, msi = 0, msix = 0;
14template <
class Config>
21 !config.read8(14, header) || (header & 0x7f) != 0 || !config.read16(4, state.command) ||
22 !config.read16(6, status) || !config.read8(0x3c, state.interruptLine) ||
23 !config.read8(0x3d, state.interruptPin))
27 if (state.interruptPin < 1 || state.interruptPin > 4 || state.interruptLine >= 16 ||
28 !(0xdef8U & (1U << state.interruptLine)))
30 for (
unsigned i = 0; i < 6; ++i)
31 if (!config.read32(0x10 + 4 * i, state.bars[i]))
34 if ((status & 0x10) && !config.read8(0x34, cap))
36 uint64_t occupied = 0;
38 if (cap < 0x40 || (cap & 3))
40 uint8_t type = 0, next = 0;
42 if (!config.read8(cap, type) || !config.read8(cap + 1, next) ||
43 !config.read16(cap + 2, control))
51 }
else if (type == 5) {
55 bytes = (control & 0x80) ? 14 : 10;
58 }
else if (type == 0x11) {
64 if (cap + bytes > 256)
66 for (
unsigned slot = cap / 4; slot < (cap + bytes + 3) / 4; ++slot) {
67 if (occupied & (1ULL << slot))
69 occupied |= 1ULL << slot;
73 if (!config.read16(cap + 4, pmcsr) || (pmcsr & 3))
82template <
class Config>
83bool disableMessageInterrupts(
Config& config,
const State& state) {
84 const uint8_t capabilities[] = {state.msi, state.msix};
85 for (uint8_t cap : capabilities) {
88 uint16_t control = 0, actual = 0;
89 if (!config.read16(cap + 2, control))
91 const uint16_t desired = cap == state.msi ? control & ~1U : (control | 0x4000U) & ~0x8000U;
92 if (!config.write16(cap + 2, desired) || !config.read16(cap + 2, actual) || actual != desired)
98template <
class Config>
99bool resourcesUnchanged(
Config& config,
const State& state) {
100 for (
unsigned i = 0; i < 6; ++i) {
102 if (!config.read32(0x10 + 4 * i, bar) || bar != state.bars[i])
105 uint8_t line = 0, pin = 0;
106 return config.read8(0x3c, line) && config.read8(0x3d, pin) && line == state.interruptLine &&
107 pin == state.interruptPin;