X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Fdrv%2Fpci.c;h=8745080b0a3f1f2b808af629b7da6b8d8f1411cb;hb=ceae45d80582dcb433cd26dcd6aad1c17229779d;hp=f75b5acb708698c6ded7129d061438165146d886;hpb=8ed2da7e1d43b4aba384946ad5b9779071d2a40f;p=tpg%2Facess2.git diff --git a/Kernel/drv/pci.c b/Kernel/drv/pci.c index f75b5acb..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,15 +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); if(Size != 4) - dword = PCI_CfgReadDWord(dev->bus, dev->slot, dev->fcn, Offset/4); + dword = PCI_CfgReadDWord(addr); switch(Size) { case 1: @@ -393,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); } /** @@ -424,32 +434,35 @@ Uint32 PCI_GetBAR(tPCIDev id, int BARNum) */ 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); - } + 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%04x", info->oc); - //#endif +// #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; @@ -468,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; }