X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Fdrv%2Fpci.c;h=8745080b0a3f1f2b808af629b7da6b8d8f1411cb;hb=7536e8afcc3018c4ca2a4aa8f8422cf86a6c188c;hp=2e107a794a24c8e024c253e0e9cb34d90ba00528;hpb=7177e27ebe90ae180a0c645f319f39c89f07373b;p=tpg%2Facess2.git diff --git a/Kernel/drv/pci.c b/Kernel/drv/pci.c index 2e107a79..8745080b 100644 --- a/Kernel/drv/pci.c +++ b/Kernel/drv/pci.c @@ -8,27 +8,17 @@ #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 { Uint16 bus, slot, fcn; Uint16 vendor, device; - union { - struct { - Uint8 class, subclass; - }; - Uint16 oc; - }; - Uint8 revision, progif; + Uint32 class; // Class:Subclass:ProgIf + Uint8 revision; Uint32 ConfigCache[256/4]; char Name[8]; tVFS_Node Node; @@ -44,6 +34,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); @@ -53,6 +44,15 @@ MODULE_DEFINE(0, 0x0100, PCI, PCI_Install, NULL, NULL); int giPCI_InodeHandle = -1; int giPCI_DeviceCount = 0; tPCIDevice *gPCI_Devices = NULL; +tVFS_NodeType gPCI_RootNodeType = { + .TypeName = "PCI Root Node", + .ReadDir = PCI_int_ReadDirRoot, + .FindDir = PCI_int_FindDirRoot +}; +tVFS_NodeType gPCI_DevNodeType = { + .TypeName = "PCI Dev Node", + .Read = PCI_int_ReadDevice +}; tDevFS_Driver gPCI_DriverStruct = { NULL, "pci", { @@ -60,8 +60,7 @@ tDevFS_Driver gPCI_DriverStruct = { .Size = -1, .NumACLs = 1, .ACLs = &gVFS_ACL_EveryoneRX, - .ReadDir = PCI_int_ReadDirRoot, - .FindDir = PCI_int_FindDirRoot + .Type = &gPCI_RootNodeType } }; Uint32 *gaPCI_PortBitmap = NULL; @@ -147,7 +146,7 @@ int PCI_ScanBus(int BusID, int bFill) if(!PCI_int_EnumDevice(BusID, dev, fcn, &devInfo)) continue; - if(devInfo.oc == PCI_OC_PCIBRIDGE) + if(devInfo.class == PCI_OC_PCIBRIDGE) { #if LIST_DEVICES if( !bFill ) @@ -162,8 +161,8 @@ int PCI_ScanBus(int BusID, int bFill) { #if LIST_DEVICES if( !bFill ) - Log_Log("PCI", "Device %i,%i:%i %04x => 0x%04x:0x%04x", - BusID, dev, fcn, devInfo.oc, devInfo.vendor, devInfo.device); + Log_Log("PCI", "Device %i,%i:%i %06x => 0x%04x:0x%04x", + BusID, dev, fcn, devInfo.class, devInfo.vendor, devInfo.device); #endif } @@ -276,7 +275,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 1; if(Vendor) *Vendor = dev->vendor; if(Device) *Device = dev->device; - if(Class) *Class = dev->oc; + if(Class) *Class = dev->class; return 0; } -int PCI_GetDeviceVersion(tPCIDev ID, Uint8 *Revision, Uint8 *ProgIF) +int PCI_GetDeviceVersion(tPCIDev ID, Uint8 *Revision) { tPCIDevice *dev = &gPCI_Devices[ID]; if(ID < 0 || ID >= giPCI_DeviceCount) return 1; if(Revision) *Revision = dev->revision; - if(ProgIF) *ProgIF = dev->progif; return 0; } @@ -339,10 +337,20 @@ int PCI_GetDeviceSubsys(tPCIDev ID, Uint16 *SubsystemVendor, Uint16 *SubsystemID return 0; } +Uint32 PCI_int_GetBusAddr(Uint16 Bus, Uint16 Slot, Uint16 Fcn, Uint8 Offset) +{ + Bus &= 0xFF; + Slot &= 0x1F; + Fcn &= 7; + Offset &= 0xFC; + return ((Uint32)Bus << 16) | (Slot << 11) | (Fcn << 8) | (Offset & 0xFC); +} + Uint32 PCI_ConfigRead(tPCIDev ID, int Offset, int Size) { tPCIDevice *dev; - Uint32 dword; + Uint32 dword, addr; + if( ID < 0 || ID >= giPCI_DeviceCount ) return 0; if( Offset < 0 || Offset > 256 ) return 0; @@ -350,8 +358,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 +375,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 +403,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 +429,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 & 0xFF; + info->class = tmp >> 8; + +// #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%06x", info->class); +// #endif // Make node name info->Name[0] = '0' + bus/10; @@ -552,7 +481,7 @@ int PCI_int_EnumDevice(Uint16 bus, Uint16 slot, Uint16 fcn, tPCIDevice *info) info->Node.NumACLs = 1; info->Node.ACLs = &gVFS_ACL_EveryoneRO; - info->Node.Read = PCI_int_ReadDevice; + info->Node.Type = &gPCI_RootNodeType; return 1; }