More PCI stuff - BARs.

alentours-dev
q3k 2012-10-28 18:09:42 +01:00
parent 46a5fb8642
commit 43e3aa7e82
2 changed files with 94 additions and 1 deletions

View File

@ -43,15 +43,51 @@ namespace Alentours
u8 MultiFunction : 1;
u8 BIST;
} __attribute__((packed)) TPCIHeaderCommon;
typedef union
{
u32 Value;
struct
{
u8 Zero : 1;
u8 Type : 2;
u8 Prefetchable : 1;
u32 Address : 28;
} __attribute__((packed)) MemoryBAR;
struct
{
u8 One : 1;
u8 Reserved : 1;
u32 Address : 30;
} __attribute__((packed)) IOBAR;
} TPCIBAR;
typedef struct
{
TPCIBAR BAR[6];
u32 CardbusCISPointer;
u16 SubsystemVID;
u16 SubsystemID;
u32 ExpansionROMAddress;
u8 Capabilities;
u32 Reserved0 : 24;
u32 Reserved1;
u8 InterruptLine;
u8 InterruptPIN;
u8 MinGrant;
u8 MaxLatency;
} __attribute__((packed)) TPCIHeaderDevice;
class CPCIDevice
{
private:
u16 m_Bus, m_Device;
TPCIHeaderCommon m_Header;
TPCIHeaderDevice *m_DeviceHeader;
public:
CPCIDevice(u16 Bus, u16 Device);
u32 ConfigRead(u16 Function, u16 Offset);
void ConfigWrite(u16 Function, u16 Offset, u32 Data);
};
class CPCIManager

View File

@ -105,13 +105,28 @@ u32 CPCIDevice::ConfigRead(u16 Function, u16 Offset)
return kinl(PCI_CONFIG_DATA);
}
void CPCIDevice::ConfigWrite(u16 Function, u16 Offset, u32 Data)
{
TPCIConfigAddress Address;
Address.Fields.Zero = 0;
Address.Fields.Register = Offset >> 2;
Address.Fields.Function = Function;
Address.Fields.Device = m_Device;
Address.Fields.Bus = m_Bus;
Address.Fields.Reserved = 0;
Address.Fields.Enable = 1;
koutl(PCI_CONFIG_ADDRESS, Address.Value);
koutl(PCI_CONFIG_DATA, Data);
}
CPCIDevice::CPCIDevice(u16 Bus, u16 Device)
{
m_Bus = Bus;
m_Device = Device;
m_DeviceHeader = 0;
kprintf("PCI device [%i:%i]\n", Bus, Device);
for (u8 i = 0; i < sizeof(m_Header); i += 4)
{
u32 Value = ConfigRead(0, i);
@ -134,6 +149,7 @@ CPCIDevice::CPCIDevice(u16 Bus, u16 Device)
kprintf("Unknown.\n");
break;
}
kprintf(" Info: ");
const s8 *VendorName, *ProductName, *ProductDescription;
if (CPCIManager::DBGetVendor(m_Header.VendorID, &VendorName))
@ -141,6 +157,47 @@ CPCIDevice::CPCIDevice(u16 Bus, u16 Device)
if (CPCIManager::DBGetProduct(m_Header.VendorID, m_Header.ProductID, &ProductName, &ProductDescription))
kprintf(" %s %s", ProductName, ProductDescription);
kprintf("\n");
switch (m_Header.HeaderType)
{
case 0x00:
{
m_DeviceHeader = new TPCIHeaderDevice;
for (u8 i = 0; i < sizeof(TPCIHeaderDevice); i += 4)
((u32 *)m_DeviceHeader)[i/4] = ConfigRead(0, 0x10 + i);
for (u8 i = 0; i < 6; i++)
{
TPCIBAR *BAR = &m_DeviceHeader->BAR[i];
u32 Value = BAR->Value;
if (Value == 0)
continue;
kprintf(" BAR%i: ", i);
if (Value & 1)
{
kprintf("I/O ");
kprintf("Value: %x\n", Value);
}
else
{
if (BAR->MemoryBAR.Type != 0x00)
{
kprintf(" non 32-bit, ignoring.\n");
continue;
}
kprintf("Memory ");
kprintf("Value: %x ", Value);
ConfigWrite(0, 0x10 + (i * 4), 0xFFFFFFFF);
u32 NewValue = ConfigRead(0, 0x10 + (i * 4));
ConfigWrite(0, 0x10 + (i * 4), Value);
u32 Size = ~(NewValue & ~(0b1111)) + 1;
kprintf("Size: %x (%ik)\n", Size, Size/1024);
}
}
break;
}
}
}
cb::CVector<CPCIDevice> CPCIManager::m_Devices;