kolibrios/programs/system/drivers/rhd/pci.c

160 lines
3.5 KiB
C
Raw Normal View History

#include "common.h"
#include "pci.h"
int
pciGetBaseSize(int bus, int devfn, int index, Bool destructive, Bool *min)
{
int offset;
CARD32 addr1;
CARD32 addr2;
CARD32 mask1;
CARD32 mask2;
int bits = 0;
/*
* silently ignore bogus index values. Valid values are 0-6. 0-5 are
* the 6 base address registers, and 6 is the ROM base address register.
*/
if (index < 0 || index > 6)
return 0;
if (min)
*min = destructive;
/* Get the PCI offset */
if (index == 6)
offset = PCI_MAP_ROM_REG;
else
offset = PCI_MAP_REG_START + (index << 2);
addr1 = PciRead32(bus, devfn, offset);
/*
* Check if this is the second part of a 64 bit address.
* XXX need to check how endianness affects 64 bit addresses.
*/
if (index > 0 && index < 6) {
addr2 = PciRead32(bus, devfn, offset - 4);
if (PCI_MAP_IS_MEM(addr2) && PCI_MAP_IS64BITMEM(addr2))
return 0;
}
if (destructive) {
PciWrite32(bus, devfn, offset, 0xffffffff);
mask1 = PciRead32(bus, devfn, offset);
PciWrite32(bus, devfn, offset, addr1);
} else {
mask1 = addr1;
}
/* Check if this is the first part of a 64 bit address. */
if (index < 5 && PCI_MAP_IS_MEM(mask1) && PCI_MAP_IS64BITMEM(mask1))
{
if (PCIGETMEMORY(mask1) == 0)
{
addr2 = PciRead32(bus, devfn, offset + 4);
if (destructive)
{
PciWrite32(bus, devfn, offset + 4, 0xffffffff);
mask2 = PciRead32(bus, devfn, offset + 4);
PciWrite32(bus, devfn, offset + 4, addr2);
}
else
{
mask2 = addr2;
}
if (mask2 == 0)
return 0;
bits = 32;
while ((mask2 & 1) == 0)
{
bits++;
mask2 >>= 1;
}
if (bits > 32)
return bits;
}
}
if (index < 6)
if (PCI_MAP_IS_MEM(mask1))
mask1 = PCIGETMEMORY(mask1);
else
mask1 = PCIGETIO(mask1);
else
mask1 = PCIGETROM(mask1);
if (mask1 == 0)
return 0;
bits = 0;
while ((mask1 & 1) == 0) {
bits++;
mask1 >>= 1;
}
/* I/O maps can be no larger than 8 bits */
if ((index < 6) && PCI_MAP_IS_IO(addr1) && bits > 8)
bits = 8;
/* ROM maps can be no larger than 24 bits */
if (index == 6 && bits > 24)
bits = 24;
return bits;
}
/*
int chipRev;
int subsysVendor;
int subsysCard;
int bus;
int devfn;
// int func;
int class;
int subclass;
int interface;
memType memBase[6];
memType ioBase[6];
int size[6];
unsigned char type[6];
memType biosBase;
int biosSize;
*/
int pciGetInfo(pciVideoPtr pci)
{
CARD32 reg0,reg2C;
int i;
reg0 = PciRead32(pci->bus,pci->devfn, 0);
reg2C = PciRead32(pci->bus,pci->devfn, 0x2C);
pci->vendor = reg0 & 0xFFFF;
pci->devtype = reg0 >> 16;
pci->subsysVendor = reg2C & 0xFFFF;
pci->subsysCard = reg2C >> 16;
for (i = 0; i < 6; i++)
{
CARD32 base;
base = PciRead32(pci->bus,pci->devfn, PCI_MAP_REG_START + (i << 2));
if(base)
{
if (base & PCI_MAP_IO)
{
pci->ioBase[i] = (memType)PCIGETIO(base);
pci->type[i] = base & PCI_MAP_IO_ATTR_MASK;
}
else
{
pci->type[i] = base & PCI_MAP_MEMORY_ATTR_MASK;
pci->memBase[i] = (memType)PCIGETMEMORY(base);
}
}
pci->size[i] =
pciGetBaseSize(pci->bus,pci->devfn, i, TRUE, &pci->validSize);
}
}