136 lines
2.7 KiB
C++
136 lines
2.7 KiB
C++
#pragma once
|
|
#include <luna/Types.h>
|
|
|
|
namespace PCI
|
|
{
|
|
enum Field : u32
|
|
{
|
|
VendorID = 0x00,
|
|
DeviceID = 0x02,
|
|
Command = 0x04,
|
|
Status = 0x06,
|
|
|
|
RevisionID = 0x08,
|
|
ProgIF = 0x09,
|
|
Subclass = 0x0a,
|
|
Class = 0x0b,
|
|
|
|
HeaderType = 0x0e,
|
|
|
|
BAR0 = 0x10,
|
|
BAR1 = 0x14,
|
|
BAR2 = 0x18,
|
|
BAR3 = 0x1c,
|
|
|
|
SecondaryBus = 0x19,
|
|
|
|
InterruptLine = 0x3c,
|
|
};
|
|
|
|
enum CommandField : u16
|
|
{
|
|
CMD_IO_SPACE = 1 << 0,
|
|
CMD_MEMORY_SPACE = 1 << 1,
|
|
CMD_BUS_MASTER = 1 << 2,
|
|
CMD_SPECIAL_CYCLES = 1 << 3,
|
|
CMD_MEMORY_WRITE_AND_INVALIDATE = 1 << 4,
|
|
CMD_VGA_PALETTE_SNOOP = 1 << 5,
|
|
CMD_PARITY_ERROR_RESPONSE = 1 << 6,
|
|
CMD_SERR = 1 << 8,
|
|
CMD_FAST_BACK_TO_BACK = 1 << 9,
|
|
CMD_INTERRUPT_DISABLE = 1 << 10,
|
|
};
|
|
|
|
struct BAR
|
|
{
|
|
public:
|
|
BAR(u32 raw);
|
|
|
|
bool is_iospace()
|
|
{
|
|
return m_raw & 0x01;
|
|
}
|
|
|
|
bool is_memory_space()
|
|
{
|
|
return !is_iospace();
|
|
}
|
|
|
|
u16 port()
|
|
{
|
|
return (u16)(m_raw & 0xfffffffc);
|
|
}
|
|
|
|
u8 type()
|
|
{
|
|
return (m_raw >> 1) & 0x03;
|
|
}
|
|
|
|
bool is_prefetchable()
|
|
{
|
|
return m_raw & (1 << 3);
|
|
}
|
|
|
|
u32 address_32bit()
|
|
{
|
|
return m_raw & 0xFFFFFFF0;
|
|
}
|
|
|
|
private:
|
|
u32 m_raw;
|
|
};
|
|
|
|
struct Device
|
|
{
|
|
struct ID
|
|
{
|
|
u16 vendor;
|
|
u16 device;
|
|
};
|
|
|
|
struct Type
|
|
{
|
|
u8 klass;
|
|
u8 subclass;
|
|
u8 prog_if;
|
|
};
|
|
|
|
struct Address
|
|
{
|
|
u32 bus;
|
|
u32 slot;
|
|
u32 function;
|
|
};
|
|
|
|
BAR getBAR(u8 index) const;
|
|
|
|
ID id;
|
|
Type type;
|
|
Address address;
|
|
};
|
|
|
|
typedef void (*Callback)(const Device&);
|
|
|
|
struct Match
|
|
{
|
|
i16 klass { -1 };
|
|
i16 subclass { -1 };
|
|
i16 prog_if { -1 };
|
|
};
|
|
|
|
constexpr u16 INVALID_ID = 0xFFFF;
|
|
|
|
// Architecture-dependent.
|
|
u8 read8(const Device::Address& address, u32 field);
|
|
u16 read16(const Device::Address& address, u32 field);
|
|
u32 read32(const Device::Address& address, u32 field);
|
|
void write8(const Device::Address& address, u32 field, u8 value);
|
|
void write16(const Device::Address& address, u32 field, u16 value);
|
|
void write32(const Device::Address& address, u32 field, u32 value);
|
|
|
|
Device::ID read_id(const Device::Address& address);
|
|
Device::Type read_type(const Device::Address& address);
|
|
|
|
void scan(Callback callback, Match match);
|
|
}
|