#include <vfs.h>\r
#include <fs_devfs.h>\r
#include <drv_pci.h>\r
+#include <drv_pci_int.h>\r
\r
#define LIST_DEVICES 1\r
\r
-// === IMPORTS ===\r
-extern Uint32 PCI_CfgReadDWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset);\r
-extern void PCI_CfgWriteDWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset, Uint32 data);\r
-extern Uint16 PCI_CfgReadWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset);\r
-extern Uint8 PCI_CfgReadByte(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset);\r
-\r
// === STRUCTURES ===\r
typedef struct sPCIDevice\r
{\r
Uint16 bus, slot, fcn;\r
Uint16 vendor, device;\r
- union {\r
- struct {\r
- Uint8 class, subclass;\r
- };\r
- Uint16 oc;\r
- };\r
- Uint8 revision, progif;\r
+ Uint32 class; // Class:Subclass:ProgIf\r
+ Uint8 revision;\r
Uint32 ConfigCache[256/4];\r
char Name[8];\r
tVFS_Node Node;\r
\r
char *PCI_int_ReadDirRoot(tVFS_Node *node, int pos);\r
tVFS_Node *PCI_int_FindDirRoot(tVFS_Node *node, const char *filename);\r
+Uint32 PCI_int_GetBusAddr(Uint16 Bus, Uint16 Slot, Uint16 Fcn, Uint8 Offset);\r
Uint64 PCI_int_ReadDevice(tVFS_Node *node, Uint64 pos, Uint64 length, void *buffer);\r
int PCI_int_EnumDevice(Uint16 bus, Uint16 dev, Uint16 fcn, tPCIDevice *info);\r
\r
int giPCI_InodeHandle = -1;\r
int giPCI_DeviceCount = 0;\r
tPCIDevice *gPCI_Devices = NULL;\r
+tVFS_NodeType gPCI_RootNodeType = {\r
+ .TypeName = "PCI Root Node",\r
+ .ReadDir = PCI_int_ReadDirRoot,\r
+ .FindDir = PCI_int_FindDirRoot\r
+};\r
+tVFS_NodeType gPCI_DevNodeType = {\r
+ .TypeName = "PCI Dev Node",\r
+ .Read = PCI_int_ReadDevice\r
+};\r
tDevFS_Driver gPCI_DriverStruct = {\r
NULL, "pci",\r
{\r
.Size = -1,\r
.NumACLs = 1,\r
.ACLs = &gVFS_ACL_EveryoneRX,\r
- .ReadDir = PCI_int_ReadDirRoot,\r
- .FindDir = PCI_int_FindDirRoot\r
+ .Type = &gPCI_RootNodeType\r
}\r
};\r
Uint32 *gaPCI_PortBitmap = NULL;\r
if(!PCI_int_EnumDevice(BusID, dev, fcn, &devInfo))\r
continue;\r
\r
- if(devInfo.oc == PCI_OC_PCIBRIDGE)\r
+ if(devInfo.class == PCI_OC_PCIBRIDGE)\r
{\r
#if LIST_DEVICES\r
- Log_Log("PCI", "Bridge @ %i,%i:%i (0x%x:0x%x)",\r
- BusID, dev, fcn, devInfo.vendor, devInfo.device);\r
+ if( !bFill )\r
+ Log_Log("PCI", "Bridge @ %i,%i:%i (0x%x:0x%x)",\r
+ BusID, dev, fcn, devInfo.vendor, devInfo.device);\r
#endif\r
//TODO: Handle PCI-PCI Bridges\r
//PCI_ScanBus(devInfo.???, bFill);\r
else\r
{\r
#if LIST_DEVICES\r
- Log_Log("PCI", "Device %i,%i:%i %04x => 0x%04x:0x%04x",\r
- BusID, dev, fcn, devInfo.oc, devInfo.vendor, devInfo.device);\r
+ if( !bFill )\r
+ Log_Log("PCI", "Device %i,%i:%i %06x => 0x%04x:0x%04x",\r
+ BusID, dev, fcn, devInfo.class, devInfo.vendor, devInfo.device);\r
#endif\r
}\r
\r
tPCIDev PCI_GetDevice(Uint16 vendor, Uint16 device, int idx)\r
{\r
int i, j=0;\r
- for(i=0;i<giPCI_DeviceCount;i++)\r
+ for( i = 0; i < giPCI_DeviceCount; i ++ )\r
{\r
if(gPCI_Devices[i].vendor != vendor) continue;\r
if(gPCI_Devices[i].device != device) continue;\r
* \param mask Mask for class comparison\r
* \param prev ID of previous device (-1 for no previous)\r
*/\r
-tPCIDev PCI_GetDeviceByClass(Uint16 class, Uint16 mask, tPCIDev prev)\r
+tPCIDev PCI_GetDeviceByClass(Uint32 class, Uint32 mask, tPCIDev prev)\r
{\r
int i;\r
// Check if prev is negative (meaning get first)\r
\r
for( ; i < giPCI_DeviceCount; i++ )\r
{\r
- if((gPCI_Devices[i].oc & mask) == class)\r
+ if((gPCI_Devices[i].class & mask) == class)\r
return i;\r
}\r
return -1;\r
}\r
\r
-int PCI_GetDeviceInfo(tPCIDev ID, Uint16 *Vendor, Uint16 *Device, Uint16 *Class)\r
+int PCI_GetDeviceInfo(tPCIDev ID, Uint16 *Vendor, Uint16 *Device, Uint32 *Class)\r
{\r
tPCIDevice *dev = &gPCI_Devices[ID];\r
if(ID < 0 || ID >= giPCI_DeviceCount) return 1;\r
\r
if(Vendor) *Vendor = dev->vendor;\r
if(Device) *Device = dev->device;\r
- if(Class) *Class = dev->oc;\r
+ if(Class) *Class = dev->class;\r
return 0;\r
}\r
\r
-int PCI_GetDeviceVersion(tPCIDev ID, Uint8 *Revision, Uint8 *ProgIF)\r
+int PCI_GetDeviceVersion(tPCIDev ID, Uint8 *Revision)\r
{\r
tPCIDevice *dev = &gPCI_Devices[ID];\r
if(ID < 0 || ID >= giPCI_DeviceCount) return 1;\r
\r
if(Revision) *Revision = dev->revision;\r
- if(ProgIF) *ProgIF = dev->progif;\r
return 0;\r
}\r
\r
return 0;\r
}\r
\r
+Uint32 PCI_int_GetBusAddr(Uint16 Bus, Uint16 Slot, Uint16 Fcn, Uint8 Offset)\r
+{\r
+ Bus &= 0xFF;\r
+ Slot &= 0x1F;\r
+ Fcn &= 7;\r
+ Offset &= 0xFC;\r
+ return ((Uint32)Bus << 16) | (Slot << 11) | (Fcn << 8) | (Offset & 0xFC);\r
+}\r
+\r
Uint32 PCI_ConfigRead(tPCIDev ID, int Offset, int Size)\r
{\r
tPCIDevice *dev;\r
- Uint32 dword;\r
+ Uint32 dword, addr;\r
+ \r
if( ID < 0 || ID >= giPCI_DeviceCount ) return 0;\r
if( Offset < 0 || Offset > 256 ) return 0;\r
\r
if( Offset & (Size - 1) ) return 0;\r
\r
dev = &gPCI_Devices[ID];\r
+ addr = PCI_int_GetBusAddr(dev->bus, dev->slot, dev->fcn, Offset);\r
\r
- dword = PCI_CfgReadDWord(dev->bus, dev->slot, dev->fcn, Offset / 4);\r
+ dword = PCI_CfgReadDWord(addr);\r
gPCI_Devices[ID].ConfigCache[Offset/4] = dword;\r
switch( Size )\r
{\r
void PCI_ConfigWrite(tPCIDev ID, int Offset, int Size, Uint32 Value)\r
{\r
tPCIDevice *dev;\r
- Uint32 dword;\r
+ Uint32 dword, addr;\r
int shift;\r
if( ID < 0 || ID >= giPCI_DeviceCount ) return ;\r
if( Offset < 0 || Offset > 256 ) return ;\r
\r
dev = &gPCI_Devices[ID];\r
+ addr = PCI_int_GetBusAddr(dev->bus, dev->slot, dev->fcn, Offset);\r
\r
- dword = PCI_CfgReadDWord(dev->bus, dev->slot, dev->fcn, Offset/4);\r
+ if(Size != 4)\r
+ dword = PCI_CfgReadDWord(addr);\r
switch(Size)\r
{\r
case 1:\r
default:\r
return;\r
}\r
- PCI_CfgWriteDWord(dev->bus, dev->slot, dev->fcn, Offset/4, dword);\r
+ PCI_CfgWriteDWord(addr, dword);\r
}\r
\r
/**\r
return gPCI_Devices[id].ConfigCache[4+BARNum];\r
}\r
\r
-#if 0\r
-/**\r
- * \brief Assign a port to a BAR\r
- */\r
-Uint16 PCI_AssignPort(tPCIDev ID, int bar, int Count)\r
-{\r
- #if 1\r
- Uint16 rv;\r
- tPCIDevice *dev;\r
- \r
- if(id < 0 || id >= giPCI_DeviceCount) return 0;\r
- if(bar < 0 || bar >= 6) return 0;\r
- dev = &gPCI_Devices[id];\r
- \r
- rv = PCI_CfgReadDWord( dev->bus, dev->slot, dev->fcn, 0x10+bar*4 );\r
- if(rv & 1) return rv & ~1;\r
- return 0;\r
- #else\r
- Uint16 portVals;\r
- int gran=0;\r
- int i, j;\r
- tPCIDevice *dev;\r
- \r
- //LogF("PCI_AssignPort: (id=%i,bar=%i,count=%i)\n", id, bar, count);\r
- \r
- if(id < 0 || id >= giPCI_DeviceCount) return 0;\r
- if(bar < 0 || bar > 5) return 0;\r
- \r
- dev = &gPCI_Devices[id];\r
- \r
- PCI_CfgWriteDWord( dev->bus, dev->slot, dev->fcn, 0x10+bar*4, -1 );\r
- portVals = PCI_CfgReadDWord( dev->bus, dev->slot, dev->fcn, 0x10+bar*4 );\r
- dev->ConfigCache[4+bar] = portVals;\r
- //LogF(" PCI_AssignPort: portVals = 0x%x\n", portVals);\r
- \r
- // Check for IO port\r
- if( !(portVals & 1) ) return 0;\r
- \r
- // Mask out final bit\r
- portVals &= ~1;\r
- \r
- // Get Granuality\r
- #if ARCHDIR_IS_x86 || ARCHDIR_IS_x86_64\r
- __asm__ __volatile__ ("bsf %%eax, %%ecx" : "=c" (gran) : "a" (portVals) );\r
- gran = 1 << gran;\r
- #else\r
- {\r
- for(gran = 1; gran && !(portVals & gran); gran <<= 1);\r
- }\r
- #endif\r
- //LogF(" PCI_AssignPort: gran = 0x%x\n", gran);\r
- \r
- // Find free space\r
- portVals = 0;\r
- for( i = 0; i < 1<<16; i += gran )\r
- {\r
- for( j = 0; j < count; j ++ )\r
- {\r
- if( gaPCI_PortBitmap[ (i+j)>>5 ] & 1 << ((i+j)&0x1F) )\r
- break;\r
- }\r
- if(j == count) {\r
- portVals = i;\r
- break;\r
- }\r
- }\r
- \r
- if(portVals)\r
- {\r
- for( j = 0; j < count; j ++ )\r
- {\r
- if( gaPCI_PortBitmap[ (portVals+j)>>5 ] |= 1 << ((portVals+j)&0x1F) )\r
- break;\r
- }\r
- PCI_CfgWriteDWord( dev->bus, dev->slot, dev->fcn, 0x10+bar*4, portVals|1 );\r
- dev->ConfigCache[4+bar] = portVals|1;\r
- }\r
- \r
- // Return\r
- //LogF("PCI_AssignPort: RETURN 0x%x\n", portVals);\r
- return portVals;\r
- #endif\r
-}\r
-#endif\r
-\r
/**\r
* \brief Get device information for a slot/function\r
*/\r
int PCI_int_EnumDevice(Uint16 bus, Uint16 slot, Uint16 fcn, tPCIDevice *info)\r
{\r
- Uint16 vendor;\r
+ Uint32 vendor_dev, tmp;\r
int i;\r
- \r
- vendor = PCI_CfgReadWord(bus, slot, fcn, 0x0|0);\r
- if(vendor == 0xFFFF) // Invalid Device\r
+ Uint32 addr;\r
+ addr = PCI_int_GetBusAddr(bus, slot, fcn, 0); \r
+\r
+ vendor_dev = PCI_CfgReadDWord( addr );\r
+ if((vendor_dev & 0xFFFF) == 0xFFFF) // Invalid Device\r
return 0;\r
- \r
+\r
+ info->ConfigCache[0] = vendor_dev;\r
+ for( i = 1, addr += 4; i < 256/4; i ++, addr += 4 )\r
+ {\r
+ info->ConfigCache[i] = PCI_CfgReadDWord(addr);\r
+ } \r
+\r
info->bus = bus;\r
info->slot = slot;\r
info->fcn = fcn;\r
- info->vendor = vendor;\r
- info->device = PCI_CfgReadWord(bus, slot, fcn, 0x0|2);\r
- info->revision = PCI_CfgReadWord(bus, slot, fcn, 0x8|0);\r
- info->oc = PCI_CfgReadWord(bus, slot, fcn, 0x8|2);\r
- \r
- // Load Config Bytes\r
- for(i=0;i<256/4;i++)\r
- {\r
- info->ConfigCache[i] = PCI_CfgReadDWord(bus, slot, fcn, i*4);\r
- }\r
- \r
- //#if LIST_DEVICES\r
- //Log("BAR0 0x%08x BAR1 0x%08x BAR2 0x%08x", info->ConfigCache[4], info->ConfigCache[5], info->ConfigCache[6]);\r
- //Log("BAR3 0x%08x BAR4 0x%08x BAR5 0x%08x", info->ConfigCache[7], info->ConfigCache[8], info->ConfigCache[9]);\r
- //Log("Class: 0x%04x", info->oc);\r
- //#endif\r
+ info->vendor = vendor_dev & 0xFFFF;\r
+ info->device = vendor_dev >> 16;\r
+ tmp = info->ConfigCache[2];\r
+ info->revision = tmp & 0xFF;\r
+ info->class = tmp >> 8;\r
+ \r
+// #if LIST_DEVICES\r
+// Log("BAR0 0x%08x BAR1 0x%08x BAR2 0x%08x", info->ConfigCache[4], info->ConfigCache[5], info->ConfigCache[6]);\r
+// Log("BAR3 0x%08x BAR4 0x%08x BAR5 0x%08x", info->ConfigCache[7], info->ConfigCache[8], info->ConfigCache[9]);\r
+// Log("Class: 0x%06x", info->class);\r
+// #endif\r
\r
// Make node name\r
info->Name[0] = '0' + bus/10;\r
info->Node.NumACLs = 1;\r
info->Node.ACLs = &gVFS_ACL_EveryoneRO;\r
\r
- info->Node.Read = PCI_int_ReadDevice;\r
+ info->Node.Type = &gPCI_RootNodeType;\r
\r
return 1;\r
}\r