2#ifndef PEDIGREE_PCI_MESSAGE_BAR_H
3#define PEDIGREE_PCI_MESSAGE_BAR_H
5#include "pedigree/kernel/machine/Device.h"
6#include "pedigree/kernel/machine/PciFunctionState.h"
7#include "pedigree/kernel/processor/IoBase.h"
9namespace PciFunctionState {
10inline IoBase* msixTableIo(
Device* device,
const State& state,
const MsixTable& table,
bool map) {
11 if (!device || (state.barCount != 2 && state.barCount != 6)) {
15 const auto findBar = [&](uint8_t index, uint64_t end) ->
Device::Address* {
16 if (index >= state.barCount || state.bars[index] != original.bar[index] ||
17 (state.bars[index] & 1U) ||
18 ((state.bars[index] & 6U) != 0 && (state.bars[index] & 6U) != 4)) {
21 for (uint8_t i = 0; i < index;) {
22 i += !(state.bars[i] & 1U) && (state.bars[i] & 6U) == 4 ? 2 : 1;
26 if ((state.bars[index] & 6U) == 4 &&
27 (index + 1 >= state.barCount || state.bars[index + 1] != original.bar[index + 1])) {
31 name[3] =
'0' + index;
32 for (
auto* address : device->addresses()) {
33 if (address->m_Name == name && !address->m_IsIoSpace && end <= address->m_Size)
38 const uint64_t tableEnd = uint64_t(table.offset) + uint64_t(table.vectors) * 16;
39 const uint64_t pbaEnd = uint64_t(table.pbaOffset) + uint64_t((table.vectors + 63) / 64) * 8;
41 if (!address || !findBar(table.pbaBar, pbaEnd))
45 return address->m_Io && address->m_Io->size() >= tableEnd ? address->m_Io :
nullptr;
Abstrace base class for hardware I/O capabilities.