* AcessOS/AcessBasic v0.1\r
* PCI Bus Driver\r
*/\r
-#define DEBUG 1\r
-#include <common.h>\r
+#define DEBUG 0\r
+#include <acess.h>\r
+#include <modules.h>\r
#include <vfs.h>\r
#include <fs_devfs.h>\r
#include <drv_pci.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 s_pciDevice {\r
+typedef struct sPCIDevice\r
+{\r
Uint16 bus, slot, fcn;\r
Uint16 vendor, device;\r
union {\r
- struct {Uint8 class, subclass;};\r
+ struct {\r
+ Uint8 class, subclass;\r
+ };\r
Uint16 oc;\r
};\r
- Uint16 revision;\r
+ Uint8 revision, progif;\r
Uint32 ConfigCache[256/4];\r
char Name[8];\r
tVFS_Node Node;\r
-} t_pciDevice;\r
+} tPCIDevice;\r
\r
// === CONSTANTS ===\r
#define SPACE_STEP 5\r
\r
// === PROTOTYPES ===\r
int PCI_Install(char **Arguments);\r
-char *PCI_ReadDirRoot(tVFS_Node *node, int pos);\r
-tVFS_Node *PCI_FindDirRoot(tVFS_Node *node, char *filename);\r
-Uint64 PCI_ReadDevice(tVFS_Node *node, Uint64 pos, Uint64 length, void *buffer);\r
+ int PCI_ScanBus(int ID, int bFill);\r
\r
- int PCI_CountDevices(Uint16 vendor, Uint16 device, Uint16 fcn);\r
- int PCI_GetDevice(Uint16 vendor, Uint16 device, Uint16 fcn, int idx);\r
- int PCI_GetDeviceByClass(Uint16 class, Uint16 mask, int prev);\r
-Uint8 PCI_GetIRQ(int id);\r
-Uint32 PCI_GetBAR0(int id);\r
-Uint32 PCI_GetBAR1(int id);\r
-Uint32 PCI_GetBAR3(int id);\r
-Uint32 PCI_GetBAR4(int id);\r
-Uint32 PCI_GetBAR5(int id);\r
-Uint16 PCI_AssignPort(int id, int bar, int count);\r
-\r
- int PCI_EnumDevice(Uint16 bus, Uint16 dev, Uint16 fcn, t_pciDevice *info);\r
-Uint32 PCI_CfgReadDWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset);\r
-void PCI_CfgWriteDWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset, Uint32 data);\r
-Uint16 PCI_CfgReadWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset);\r
-Uint8 PCI_CfgReadByte(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset);\r
+char *PCI_int_ReadDirRoot(tVFS_Node *node, int pos);\r
+tVFS_Node *PCI_int_FindDirRoot(tVFS_Node *node, const char *filename);\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
// === GLOBALS ===\r
-//MODULE_DEFINE(0, 0x0100, PCI, PCI_Install, NULL);\r
+MODULE_DEFINE(0, 0x0100, PCI, PCI_Install, NULL, NULL);\r
int giPCI_BusCount = 1;\r
int giPCI_InodeHandle = -1;\r
int giPCI_DeviceCount = 0;\r
-t_pciDevice *gPCI_Devices = NULL;\r
+tPCIDevice *gPCI_Devices = NULL;\r
tDevFS_Driver gPCI_DriverStruct = {\r
NULL, "pci",\r
{\r
.Size = -1,\r
.NumACLs = 1,\r
.ACLs = &gVFS_ACL_EveryoneRX,\r
- .ReadDir = PCI_ReadDirRoot,\r
- .FindDir = PCI_FindDirRoot\r
+ .ReadDir = PCI_int_ReadDirRoot,\r
+ .FindDir = PCI_int_FindDirRoot\r
}\r
};\r
- Uint32 *gaPCI_PortBitmap = NULL;\r
+Uint32 *gaPCI_PortBitmap = NULL;\r
+Uint32 gaPCI_BusBitmap[256/32];\r
\r
// === CODE ===\r
/**\r
- * \fn int PCI_Install()\r
* \brief Scan the PCI Bus for devices\r
+ * \param Arguments Boot-time parameters\r
*/\r
int PCI_Install(char **Arguments)\r
{\r
- int bus, dev, fcn, i;\r
- int space = 0;\r
- t_pciDevice devInfo;\r
- void *tmpPtr = NULL;\r
+ int i;\r
+ void *tmpPtr;\r
\r
// Build Portmap\r
gaPCI_PortBitmap = malloc( 1 << 13 );\r
+ if( !gaPCI_PortBitmap ) {\r
+ Log_Error("PCI", "Unable to allocate %i bytes for bitmap", 1 << 13);\r
+ return MODULE_ERR_MALLOC;\r
+ }\r
memset( gaPCI_PortBitmap, 0, 1 << 13 );\r
for( i = 0; i < MAX_RESERVED_PORT / 32; i ++ )\r
gaPCI_PortBitmap[i] = -1;\r
for( i = 0; i < MAX_RESERVED_PORT % 32; i ++ )\r
gaPCI_PortBitmap[MAX_RESERVED_PORT / 32] = 1 << i;\r
- //LogF("Done.\n");\r
\r
- // Scan Busses\r
- for( bus = 0; bus < giPCI_BusCount; bus++ )\r
+ // Scan Bus (Bus 0, Don't fill gPCI_Devices)\r
+ i = PCI_ScanBus(0, 0);\r
+ if(i != MODULE_ERR_OK) return i;\r
+ \r
+ if(giPCI_DeviceCount == 0) {\r
+ Log_Notice("PCI", "No devices were found");\r
+ return MODULE_ERR_NOTNEEDED;\r
+ }\r
+ \r
+ // Allocate device buffer\r
+ tmpPtr = malloc(giPCI_DeviceCount * sizeof(tPCIDevice));\r
+ if(tmpPtr == NULL) {\r
+ Log_Warning("PCI", "Malloc ERROR");\r
+ return MODULE_ERR_MALLOC;\r
+ }\r
+ gPCI_Devices = tmpPtr;\r
+ \r
+ Log_Log("PCI", "%i devices, filling structure", giPCI_DeviceCount);\r
+ \r
+ // Reset counts\r
+ giPCI_DeviceCount = 0;\r
+ giPCI_BusCount = 0;\r
+ memset(gaPCI_BusBitmap, 0, sizeof(gaPCI_BusBitmap));\r
+ // Rescan, filling the PCI device array\r
+ PCI_ScanBus(0, 1);\r
+ \r
+ // Complete Driver Structure\r
+ gPCI_DriverStruct.RootNode.Size = giPCI_DeviceCount;\r
+ \r
+ // And add to DevFS\r
+ DevFS_AddDevice(&gPCI_DriverStruct);\r
+ \r
+ return MODULE_ERR_OK;\r
+}\r
+\r
+/**\r
+ * \brief Scans a specific PCI Bus\r
+ * \param BusID PCI Bus ID to scan\r
+ * \param bFill Fill the \a gPCI_Devices array?\r
+ */\r
+int PCI_ScanBus(int BusID, int bFill)\r
+{\r
+ int dev, fcn;\r
+ tPCIDevice devInfo;\r
+ \r
+ if( gaPCI_BusBitmap[BusID/32] & (1 << (BusID%32)) )\r
+ return MODULE_ERR_OK;\r
+ \r
+ gaPCI_BusBitmap[BusID/32] |= (1 << (BusID%32));\r
+ \r
+ for( dev = 0; dev < 32; dev++ ) // 32 Devices per bus\r
{\r
- for( dev = 0; dev < 10; dev++ ) // 10 Devices per bus\r
+ for( fcn = 0; fcn < 8; fcn++ ) // Max 8 functions per device\r
{\r
- for( fcn = 0; fcn < 8; fcn++ ) // 8 functions per device\r
+ // Check if the device/function exists\r
+ if(!PCI_int_EnumDevice(BusID, dev, fcn, &devInfo))\r
+ continue;\r
+ \r
+ if(devInfo.oc == PCI_OC_PCIBRIDGE)\r
+ {\r
+ #if LIST_DEVICES\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
+ giPCI_BusCount ++;\r
+ }\r
+ else\r
{\r
- // Check if the device/function exists\r
- if(!PCI_EnumDevice(bus, dev, fcn, &devInfo))\r
- {\r
- continue;\r
- }\r
- \r
- if(giPCI_DeviceCount == space)\r
- {\r
- space += SPACE_STEP;\r
- tmpPtr = realloc(gPCI_Devices, space*sizeof(t_pciDevice));\r
- if(tmpPtr == NULL)\r
- break;\r
- gPCI_Devices = tmpPtr;\r
- }\r
- if(devInfo.oc == PCI_OC_PCIBRIDGE)\r
- {\r
- #if LIST_DEVICES\r
- Log("[PCI ] Bridge @ %i,%i:%i (0x%x:0x%x)",\r
- bus, dev, fcn, devInfo.vendor, devInfo.device);\r
- #endif\r
- giPCI_BusCount++;\r
- }\r
- devInfo.Node.Inode = giPCI_DeviceCount;\r
- memcpy(&gPCI_Devices[giPCI_DeviceCount], &devInfo, sizeof(t_pciDevice));\r
- giPCI_DeviceCount ++;\r
#if LIST_DEVICES\r
- Log("[PCI ] Device %i,%i:%i => 0x%x:0x%x",\r
- bus, dev, fcn, devInfo.vendor, devInfo.device);\r
+ if( !bFill )\r
+ Log_Log("PCI", "Device %i,%i:%i %04x => 0x%04x:0x%04x",\r
+ BusID, dev, fcn, devInfo.oc, devInfo.vendor, devInfo.device);\r
#endif\r
- \r
- // WTF is this for?\r
- if(fcn == 0) {\r
- if( !(devInfo.ConfigCache[3] & 0x800000) )\r
- break;\r
- }\r
}\r
- if(tmpPtr != gPCI_Devices)\r
+ \r
+ if( bFill ) {\r
+ devInfo.Node.Inode = giPCI_DeviceCount;\r
+ memcpy(&gPCI_Devices[giPCI_DeviceCount], &devInfo, sizeof(tPCIDevice));\r
+ }\r
+ giPCI_DeviceCount ++;\r
+ \r
+ // If bit 23 of (soemthing) is set, there are sub-functions\r
+ if(fcn == 0 && !(devInfo.ConfigCache[3] & 0x00800000) )\r
break;\r
}\r
- if(tmpPtr != gPCI_Devices)\r
- break;\r
}\r
- tmpPtr = realloc(gPCI_Devices, giPCI_DeviceCount*sizeof(t_pciDevice));\r
- if(tmpPtr == NULL)\r
- return 0;\r
- gPCI_Devices = tmpPtr;\r
- //LogF("Done.\n");\r
- \r
- // Complete Driver Structure \r
- gPCI_DriverStruct.RootNode.Size = giPCI_DeviceCount;\r
\r
- // And add to DevFS\r
- DevFS_AddDevice(&gPCI_DriverStruct);\r
- \r
- return 1;\r
+ return MODULE_ERR_OK;\r
}\r
\r
/**\r
- * \fn char *PCI_ReadDirRoot(tVFS_Node *Node, int Pos)\r
* \brief Read from Root of PCI Driver\r
*/\r
-char *PCI_ReadDirRoot(tVFS_Node *Node, int Pos)\r
+char *PCI_int_ReadDirRoot(tVFS_Node *Node, int Pos)\r
{\r
ENTER("pNode iPos", Node, Pos);\r
if(Pos < 0 || Pos >= giPCI_DeviceCount) {\r
return strdup( gPCI_Devices[Pos].Name );\r
}\r
/**\r
- * \fn tVFS_Node *PCI_FindDirRoot(tVFS_Node *node, char *filename)\r
*/\r
-tVFS_Node *PCI_FindDirRoot(tVFS_Node *node, char *filename)\r
+tVFS_Node *PCI_int_FindDirRoot(tVFS_Node *node, const char *filename)\r
{\r
int bus,slot,fcn;\r
int i;\r
}\r
\r
/**\r
- * \fn Uint64 PCI_ReadDevice(tVFS_Node *node, Uint64 pos, Uint64 length, void *buffer)\r
*/\r
-Uint64 PCI_ReadDevice(tVFS_Node *node, Uint64 pos, Uint64 length, void *buffer)\r
+Uint64 PCI_int_ReadDevice(tVFS_Node *node, Uint64 pos, Uint64 length, void *buffer)\r
{ \r
if( pos + length > 256 ) return 0;\r
\r
\r
// --- Kernel Code Interface ---\r
/**\r
- \fn int PCI_CountDevices(Uint16 vendor, Uint16 device, Uint16 fcn)\r
- \brief Counts the devices with the specified codes\r
- \param vendor Vendor ID\r
- \param device Device ID\r
- \param fcn Function ID\r
-*/\r
-int PCI_CountDevices(Uint16 vendor, Uint16 device, Uint16 fcn)\r
+ * \brief Counts the devices with the specified codes\r
+ * \param vendor Vendor ID\r
+ * \param device Device ID\r
+ */\r
+int PCI_CountDevices(Uint16 vendor, Uint16 device)\r
{\r
int i, ret=0;\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
- if(gPCI_Devices[i].fcn != fcn) continue;\r
ret ++;\r
}\r
return ret;\r
}\r
\r
/**\r
- \fn int PCI_GetDevice(Uint16 vendor, Uint16 device, Uint16 fcn, int idx)\r
- \brief Gets the ID of the specified PCI device\r
- \param vendor Vendor ID\r
- \param device Device ID\r
- \param fcn Function IDs\r
- \param idx Number of matching entry wanted\r
-*/\r
-int PCI_GetDevice(Uint16 vendor, Uint16 device, Uint16 fcn, int idx)\r
+ * \brief Gets the ID of the specified PCI device\r
+ * \param vendor Vendor ID\r
+ * \param device Device ID\r
+ * \param idx Number of matching entry wanted\r
+ */\r
+tPCIDev PCI_GetDevice(Uint16 vendor, Uint16 device, int idx)\r
{\r
- int i, j=0;\r
+ int i, j=0;\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
- if(gPCI_Devices[i].fcn != fcn) continue;\r
if(j == idx) return i;\r
j ++;\r
}\r
}\r
\r
/**\r
- * \fn int PCI_GetDeviceByClass(Uint16 class, Uint16 mask, int prev)\r
* \brief Gets the ID of a device by it's class code\r
* \param class Class Code\r
* \param mask Mask for class comparison\r
* \param prev ID of previous device (-1 for no previous)\r
*/\r
-int PCI_GetDeviceByClass(Uint16 class, Uint16 mask, int prev)\r
+tPCIDev PCI_GetDeviceByClass(Uint16 class, Uint16 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) continue;\r
- return i;\r
+ if((gPCI_Devices[i].oc & mask) == class)\r
+ return i;\r
}\r
return -1;\r
}\r
\r
-/**\r
- \fn Uint8 PCI_GetIRQ(int id)\r
-*/\r
-Uint8 PCI_GetIRQ(int id)\r
+int PCI_GetDeviceInfo(tPCIDev ID, Uint16 *Vendor, Uint16 *Device, Uint16 *Class)\r
{\r
- if(id < 0 || id >= giPCI_DeviceCount)\r
- return 0;\r
- return gPCI_Devices[id].ConfigCache[15];\r
- //return PCI_CfgReadByte( gPCI_Devices[id].bus, gPCI_Devices[id].slot, gPCI_Devices[id].fcn, 0x3C);\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
+ return 0;\r
}\r
\r
-/**\r
- \fn Uint32 PCI_GetBAR0(int id)\r
-*/\r
-Uint32 PCI_GetBAR0(int id)\r
+int PCI_GetDeviceVersion(tPCIDev ID, Uint8 *Revision, Uint8 *ProgIF)\r
{\r
- if(id < 0 || id >= giPCI_DeviceCount)\r
- return 0;\r
- return gPCI_Devices[id].ConfigCache[4];\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
-/**\r
- \fn Uint32 PCI_GetBAR1(int id)\r
-*/\r
-Uint32 PCI_GetBAR1(int id)\r
+int PCI_GetDeviceSubsys(tPCIDev ID, Uint16 *SubsystemVendor, Uint16 *SubsystemID)\r
{\r
- if(id < 0 || id >= giPCI_DeviceCount)\r
- return 0;\r
- return gPCI_Devices[id].ConfigCache[5];\r
+ tPCIDevice *dev = &gPCI_Devices[ID];\r
+ if(ID < 0 || ID >= giPCI_DeviceCount) return 1;\r
+ \r
+ if(SubsystemVendor) *SubsystemVendor = dev->ConfigCache[0x2c/4] & 0xFFFF;\r
+ if(SubsystemID) *SubsystemID = dev->ConfigCache[0x2c/4] >> 16;\r
+\r
+ return 0;\r
}\r
\r
-/**\r
- \fn Uint32 PCI_GetBAR2(int id)\r
-*/\r
-Uint32 PCI_GetBAR2(int id)\r
+Uint32 PCI_ConfigRead(tPCIDev ID, int Offset, int Size)\r
{\r
- if(id < 0 || id >= giPCI_DeviceCount)\r
+ tPCIDevice *dev;\r
+ Uint32 dword;\r
+ if( ID < 0 || ID >= giPCI_DeviceCount ) return 0;\r
+ if( Offset < 0 || Offset > 256 ) return 0;\r
+\r
+ // TODO: Should I support non-aligned reads?\r
+ if( Offset & (Size - 1) ) return 0;\r
+\r
+ dev = &gPCI_Devices[ID];\r
+\r
+ dword = PCI_CfgReadDWord(dev->bus, dev->slot, dev->fcn, Offset / 4);\r
+ gPCI_Devices[ID].ConfigCache[Offset/4] = dword;\r
+ switch( Size )\r
+ {\r
+ case 1: return (dword >> (8 * (Offset&3))) & 0xFF;\r
+ case 2: return (dword >> (8 * (Offset&2))) & 0xFFFF;\r
+ case 4: return dword;\r
+ default:\r
return 0;\r
- return gPCI_Devices[id].ConfigCache[6];\r
+ }\r
}\r
\r
-/**\r
- \fn Uint32 PCI_GetBAR3(int id)\r
-*/\r
-Uint32 PCI_GetBAR3(int id)\r
+void PCI_ConfigWrite(tPCIDev ID, int Offset, int Size, Uint32 Value)\r
{\r
- if(id < 0 || id >= giPCI_DeviceCount)\r
- return 0;\r
- return gPCI_Devices[id].ConfigCache[7];\r
+ tPCIDevice *dev;\r
+ Uint32 dword;\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
+\r
+ if(Size != 4)\r
+ dword = PCI_CfgReadDWord(dev->bus, dev->slot, dev->fcn, Offset/4);\r
+ switch(Size)\r
+ {\r
+ case 1:\r
+ shift = (Offset&3)*8;\r
+ dword &= ~(0xFF << shift);\r
+ dword |= Value << shift;\r
+ break;\r
+ case 2:\r
+ shift = (Offset&2)*8;\r
+ dword &= ~(0xFFFF << shift);\r
+ dword |= Value << shift;\r
+ break;\r
+ case 4:\r
+ dword = Value;\r
+ break;\r
+ default:\r
+ return;\r
+ }\r
+ PCI_CfgWriteDWord(dev->bus, dev->slot, dev->fcn, Offset/4, dword);\r
}\r
\r
/**\r
- \fn Uint32 PCI_GetBAR4(int id)\r
-*/\r
-Uint32 PCI_GetBAR4(int id)\r
+ * \brief Get the IRQ assigned to a device\r
+ */\r
+Uint8 PCI_GetIRQ(tPCIDev id)\r
{\r
if(id < 0 || id >= giPCI_DeviceCount)\r
return 0;\r
- return gPCI_Devices[id].ConfigCache[8];\r
+ return gPCI_Devices[id].ConfigCache[15] & 0xFF;\r
+ //return PCI_CfgReadByte( gPCI_Devices[id].bus, gPCI_Devices[id].slot, gPCI_Devices[id].fcn, 0x3C);\r
}\r
\r
/**\r
- \fn Uint32 PCI_GetBAR5(int id)\r
-*/\r
-Uint32 PCI_GetBAR5(int id)\r
+ * \brief Read the a BAR (base address register) from the PCI config space\r
+ */\r
+Uint32 PCI_GetBAR(tPCIDev id, int BARNum)\r
{\r
if(id < 0 || id >= giPCI_DeviceCount)\r
return 0;\r
- return gPCI_Devices[id].ConfigCache[9];\r
-}\r
-\r
-Uint16 PCI_AssignPort(int id, int bar, int count)\r
-{\r
- Uint16 portVals;\r
- int gran=0;\r
- int i, j;\r
- t_pciDevice *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
- __asm__ __volatile__ ("bsf %%eax, %%ecx" : "=c" (gran) : "a" (portVals) );\r
- gran = 1 << gran;\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
+ if(BARNum < 0 || BARNum >= 6)\r
+ return 0;\r
+ return gPCI_Devices[id].ConfigCache[4+BARNum];\r
}\r
\r
/**\r
- * \fn int PCI_EnumDevice(Uint16 bus, Uint16 slot, Uint16 fcn, t_pciDevice *info)\r
+ * \brief Get device information for a slot/function\r
*/\r
-int PCI_EnumDevice(Uint16 bus, Uint16 slot, Uint16 fcn, t_pciDevice *info)\r
+int PCI_int_EnumDevice(Uint16 bus, Uint16 slot, Uint16 fcn, tPCIDevice *info)\r
{\r
Uint16 vendor;\r
int i;\r
- Uint32 addr;\r
\r
vendor = PCI_CfgReadWord(bus, slot, fcn, 0x0|0);\r
if(vendor == 0xFFFF) // Invalid Device\r
info->oc = PCI_CfgReadWord(bus, slot, fcn, 0x8|2);\r
\r
// Load Config Bytes\r
- addr = 0x80000000 | ((Uint)bus<<16) | ((Uint)slot<<11) | ((Uint)fcn<<8);\r
for(i=0;i<256/4;i++)\r
{\r
- #if 1\r
- outd(0xCF8, addr);\r
- info->ConfigCache[i] = ind(0xCFC);\r
- addr += 4;\r
- #else\r
info->ConfigCache[i] = PCI_CfgReadDWord(bus, slot, fcn, i*4);\r
- #endif\r
}\r
\r
//#if LIST_DEVICES\r
info->Name[2] = '.';\r
info->Name[3] = '0' + slot/10;\r
info->Name[4] = '0' + slot%10;\r
- info->Name[5] = '.';\r
+ info->Name[5] = ':';\r
info->Name[6] = '0' + fcn;\r
info->Name[7] = '\0';\r
\r
info->Node.NumACLs = 1;\r
info->Node.ACLs = &gVFS_ACL_EveryoneRO;\r
\r
- info->Node.Read = PCI_ReadDevice;\r
+ info->Node.Read = PCI_int_ReadDevice;\r
\r
return 1;\r
}\r
\r
-Uint32 PCI_CfgReadDWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset)\r
-{\r
- Uint32 address;\r
- Uint32 data;\r
- \r
- bus &= 0xFF; // 8 Bits\r
- dev &= 0x1F; // 5 Bits\r
- func &= 0x7; // 3 Bits\r
- offset &= 0xFF; // 8 Bits\r
- \r
- address = 0x80000000 | ((Uint)bus<<16) | ((Uint)dev<<11) | ((Uint)func<<8) | (offset&0xFC);\r
- outd(0xCF8, address);\r
- \r
- data = ind(0xCFC);\r
- return (Uint32)data;\r
-}\r
-void PCI_CfgWriteDWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset, Uint32 data)\r
-{\r
- Uint32 address;\r
- \r
- bus &= 0xFF; // 8 Bits\r
- dev &= 0x1F; // 5 Bits\r
- func &= 0x7; // 3 Bits\r
- offset &= 0xFF; // 8 Bits\r
- \r
- address = 0x80000000 | ((Uint)bus<<16) | ((Uint)dev<<11) | ((Uint)func<<8) | (offset&0xFC);\r
- outd(0xCF8, address);\r
- outd(0xCFC, data);\r
-}\r
-Uint16 PCI_CfgReadWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset)\r
-{\r
- Uint32 data;\r
- \r
- bus &= 0xFF; // 8 Bits\r
- dev &= 0x1F; // 5 Bits\r
- func &= 0x7; // 3 Bits\r
- offset &= 0xFF; // 8 Bits\r
- \r
- //LogF("PCI_CfgReadWord: (bus=0x%x,dev=0x%x,func=%x,offset=0x%x)\n", bus, dev, func, offset);\r
- \r
- outd(0xCF8,\r
- 0x80000000 | ((Uint)bus<<16) | ((Uint)dev<<11) | ((Uint)func<<8) | (offset&0xFC) );\r
- \r
- data = ind(0xCFC);\r
- data >>= (offset&2)*8; //Allow Access to Upper Word\r
- //LogF("PCI_CfgReadWord: RETURN 0x%x\n", data&0xFFFF);\r
- return (Uint16)data;\r
-}\r
-\r
-Uint8 PCI_CfgReadByte(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset)\r
-{\r
- Uint32 address;\r
- Uint32 data;\r
- \r
- bus &= 0xFF; // 8 Bits\r
- dev &= 0x1F; // 4 Bits\r
- func &= 0x7; // 3 Bits\r
- offset &= 0xFF; // 8 Bits\r
- \r
- address = 0x80000000 | ((Uint)bus<<16) | ((Uint)dev<<11) | ((Uint)func<<8) | (offset&0xFC);\r
- outd(0xCF8, address);\r
- \r
- data = ind(0xCFC);\r
- data >>= (offset&3)*8; //Allow Access to Upper Word\r
- return (Uint8)data;\r
-}\r
-\r
-\r
// === EXPORTS ===\r
-/*\r
+//*\r
EXPORT(PCI_CountDevices);\r
EXPORT(PCI_GetDevice);\r
-EXPORT(PCI_AssignPort);\r
+EXPORT(PCI_GetDeviceByClass);\r
+EXPORT(PCI_GetDeviceInfo);\r
+EXPORT(PCI_GetDeviceVersion);\r
+EXPORT(PCI_GetDeviceSubsys);\r
+//EXPORT(PCI_AssignPort);\r
+EXPORT(PCI_GetBAR);\r
EXPORT(PCI_GetIRQ);\r
-*/\r
+//*/\r