X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Fdrv%2Fpci.c;h=c176f4725c8fb541c356aaba2fc0dda37502fdd8;hb=c90f683ef8d3dde9db5b78feebe5508ca3f84ff3;hp=2e107a794a24c8e024c253e0e9cb34d90ba00528;hpb=7177e27ebe90ae180a0c645f319f39c89f07373b;p=tpg%2Facess2.git diff --git a/Kernel/drv/pci.c b/Kernel/drv/pci.c index 2e107a79..c176f472 100644 --- a/Kernel/drv/pci.c +++ b/Kernel/drv/pci.c @@ -8,15 +8,10 @@ #include #include #include +#include #define LIST_DEVICES 1 -// === IMPORTS === -extern Uint32 PCI_CfgReadDWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset); -extern void PCI_CfgWriteDWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset, Uint32 data); -extern Uint16 PCI_CfgReadWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset); -extern Uint8 PCI_CfgReadByte(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset); - // === STRUCTURES === typedef struct sPCIDevice { @@ -44,6 +39,7 @@ typedef struct sPCIDevice char *PCI_int_ReadDirRoot(tVFS_Node *node, int pos); tVFS_Node *PCI_int_FindDirRoot(tVFS_Node *node, const char *filename); +Uint32 PCI_int_GetBusAddr(Uint16 Bus, Uint16 Slot, Uint16 Fcn, Uint8 Offset); Uint64 PCI_int_ReadDevice(tVFS_Node *node, Uint64 pos, Uint64 length, void *buffer); int PCI_int_EnumDevice(Uint16 bus, Uint16 dev, Uint16 fcn, tPCIDevice *info); @@ -276,7 +272,7 @@ int PCI_CountDevices(Uint16 vendor, Uint16 device) tPCIDev PCI_GetDevice(Uint16 vendor, Uint16 device, int idx) { int i, j=0; - for(i=0;i= giPCI_DeviceCount ) return 0; if( Offset < 0 || Offset > 256 ) return 0; @@ -350,8 +356,9 @@ Uint32 PCI_ConfigRead(tPCIDev ID, int Offset, int Size) if( Offset & (Size - 1) ) return 0; dev = &gPCI_Devices[ID]; + addr = PCI_int_GetBusAddr(dev->bus, dev->slot, dev->fcn, Offset); - dword = PCI_CfgReadDWord(dev->bus, dev->slot, dev->fcn, Offset / 4); + dword = PCI_CfgReadDWord(addr); gPCI_Devices[ID].ConfigCache[Offset/4] = dword; switch( Size ) { @@ -366,14 +373,16 @@ Uint32 PCI_ConfigRead(tPCIDev ID, int Offset, int Size) void PCI_ConfigWrite(tPCIDev ID, int Offset, int Size, Uint32 Value) { tPCIDevice *dev; - Uint32 dword; + Uint32 dword, addr; int shift; if( ID < 0 || ID >= giPCI_DeviceCount ) return ; if( Offset < 0 || Offset > 256 ) return ; dev = &gPCI_Devices[ID]; + addr = PCI_int_GetBusAddr(dev->bus, dev->slot, dev->fcn, Offset); - dword = PCI_CfgReadDWord(dev->bus, dev->slot, dev->fcn, Offset/4); + if(Size != 4) + dword = PCI_CfgReadDWord(addr); switch(Size) { case 1: @@ -392,7 +401,7 @@ void PCI_ConfigWrite(tPCIDev ID, int Offset, int Size, Uint32 Value) default: return; } - PCI_CfgWriteDWord(dev->bus, dev->slot, dev->fcn, Offset/4, dword); + PCI_CfgWriteDWord(addr, dword); } /** @@ -418,122 +427,40 @@ Uint32 PCI_GetBAR(tPCIDev id, int BARNum) return gPCI_Devices[id].ConfigCache[4+BARNum]; } -#if 0 -/** - * \brief Assign a port to a BAR - */ -Uint16 PCI_AssignPort(tPCIDev ID, int bar, int Count) -{ - #if 1 - Uint16 rv; - tPCIDevice *dev; - - if(id < 0 || id >= giPCI_DeviceCount) return 0; - if(bar < 0 || bar >= 6) return 0; - dev = &gPCI_Devices[id]; - - rv = PCI_CfgReadDWord( dev->bus, dev->slot, dev->fcn, 0x10+bar*4 ); - if(rv & 1) return rv & ~1; - return 0; - #else - Uint16 portVals; - int gran=0; - int i, j; - tPCIDevice *dev; - - //LogF("PCI_AssignPort: (id=%i,bar=%i,count=%i)\n", id, bar, count); - - if(id < 0 || id >= giPCI_DeviceCount) return 0; - if(bar < 0 || bar > 5) return 0; - - dev = &gPCI_Devices[id]; - - PCI_CfgWriteDWord( dev->bus, dev->slot, dev->fcn, 0x10+bar*4, -1 ); - portVals = PCI_CfgReadDWord( dev->bus, dev->slot, dev->fcn, 0x10+bar*4 ); - dev->ConfigCache[4+bar] = portVals; - //LogF(" PCI_AssignPort: portVals = 0x%x\n", portVals); - - // Check for IO port - if( !(portVals & 1) ) return 0; - - // Mask out final bit - portVals &= ~1; - - // Get Granuality - #if ARCHDIR_IS_x86 || ARCHDIR_IS_x86_64 - __asm__ __volatile__ ("bsf %%eax, %%ecx" : "=c" (gran) : "a" (portVals) ); - gran = 1 << gran; - #else - { - for(gran = 1; gran && !(portVals & gran); gran <<= 1); - } - #endif - //LogF(" PCI_AssignPort: gran = 0x%x\n", gran); - - // Find free space - portVals = 0; - for( i = 0; i < 1<<16; i += gran ) - { - for( j = 0; j < count; j ++ ) - { - if( gaPCI_PortBitmap[ (i+j)>>5 ] & 1 << ((i+j)&0x1F) ) - break; - } - if(j == count) { - portVals = i; - break; - } - } - - if(portVals) - { - for( j = 0; j < count; j ++ ) - { - if( gaPCI_PortBitmap[ (portVals+j)>>5 ] |= 1 << ((portVals+j)&0x1F) ) - break; - } - PCI_CfgWriteDWord( dev->bus, dev->slot, dev->fcn, 0x10+bar*4, portVals|1 ); - dev->ConfigCache[4+bar] = portVals|1; - } - - // Return - //LogF("PCI_AssignPort: RETURN 0x%x\n", portVals); - return portVals; - #endif -} -#endif - /** * \brief Get device information for a slot/function */ int PCI_int_EnumDevice(Uint16 bus, Uint16 slot, Uint16 fcn, tPCIDevice *info) { - Uint16 vendor; + Uint32 vendor_dev, tmp; int i; - - vendor = PCI_CfgReadWord(bus, slot, fcn, 0x0|0); - if(vendor == 0xFFFF) // Invalid Device + Uint32 addr; + addr = PCI_int_GetBusAddr(bus, slot, fcn, 0); + + vendor_dev = PCI_CfgReadDWord( addr ); + if((vendor_dev & 0xFFFF) == 0xFFFF) // Invalid Device return 0; - + + info->ConfigCache[0] = vendor_dev; + for( i = 1, addr += 4; i < 256/4; i ++, addr += 4 ) + { + info->ConfigCache[i] = PCI_CfgReadDWord(addr); + } + info->bus = bus; info->slot = slot; info->fcn = fcn; - info->vendor = vendor; - info->device = PCI_CfgReadWord(bus, slot, fcn, 0x0|2); - info->revision = PCI_CfgReadWord(bus, slot, fcn, 0x8|0); - info->oc = PCI_CfgReadWord(bus, slot, fcn, 0x8|2); - - // Load Config Bytes - for(i=0;i<256/4;i++) - { - info->ConfigCache[i] = PCI_CfgReadDWord(bus, slot, fcn, i*4); - } - - //#if LIST_DEVICES - //Log("BAR0 0x%08x BAR1 0x%08x BAR2 0x%08x", info->ConfigCache[4], info->ConfigCache[5], info->ConfigCache[6]); - //Log("BAR3 0x%08x BAR4 0x%08x BAR5 0x%08x", info->ConfigCache[7], info->ConfigCache[8], info->ConfigCache[9]); - //Log("Class: 0x%04x", info->oc); - //#endif + info->vendor = vendor_dev & 0xFFFF; + info->device = vendor_dev >> 16; + tmp = info->ConfigCache[2]; + info->revision = tmp & 0xFFFF; + info->oc = tmp >> 16; + +// #if LIST_DEVICES +// Log("BAR0 0x%08x BAR1 0x%08x BAR2 0x%08x", info->ConfigCache[4], info->ConfigCache[5], info->ConfigCache[6]); +// Log("BAR3 0x%08x BAR4 0x%08x BAR5 0x%08x", info->ConfigCache[7], info->ConfigCache[8], info->ConfigCache[9]); +// Log("Class: 0x%04x", info->oc); +// #endif // Make node name info->Name[0] = '0' + bus/10;