\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
\r
// === PROTOTYPES ===\r
int PCI_Install(char **Arguments);\r
- int PCI_ScanBus(int ID);\r
+ int PCI_ScanBus(int ID, int bFill);\r
\r
char *PCI_ReadDirRoot(tVFS_Node *node, int pos);\r
-tVFS_Node *PCI_FindDirRoot(tVFS_Node *node, char *filename);\r
+tVFS_Node *PCI_FindDirRoot(tVFS_Node *node, const char *filename);\r
Uint64 PCI_ReadDevice(tVFS_Node *node, Uint64 pos, Uint64 length, void *buffer);\r
- \r
+\r
+#if 0\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_GetBAR2(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
+#endif\r
\r
int PCI_EnumDevice(Uint16 bus, Uint16 dev, Uint16 fcn, tPCIDevice *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
\r
// === GLOBALS ===\r
MODULE_DEFINE(0, 0x0100, PCI, PCI_Install, NULL, NULL);\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
for( i = 0; i < MAX_RESERVED_PORT % 32; i ++ )\r
gaPCI_PortBitmap[MAX_RESERVED_PORT / 32] = 1 << i;\r
\r
- // Scan Bus\r
- i = PCI_ScanBus(0);\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
return MODULE_ERR_NOTNEEDED;\r
}\r
\r
- // Ensure the buffer is nice and tight\r
- tmpPtr = realloc(gPCI_Devices, giPCI_DeviceCount*sizeof(tPCIDevice));\r
- if(tmpPtr == NULL)\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
\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)\r
+int PCI_ScanBus(int BusID, int bFill)\r
{\r
int dev, fcn;\r
tPCIDevice devInfo;\r
- void *tmpPtr = NULL;\r
\r
if( gaPCI_BusBitmap[BusID/32] & (1 << (BusID%32)) )\r
return MODULE_ERR_OK;\r
if(!PCI_EnumDevice(BusID, dev, fcn, &devInfo))\r
continue;\r
\r
- // Allocate\r
- tmpPtr = realloc(gPCI_Devices, (giPCI_DeviceCount+1)*sizeof(tPCIDevice));\r
- if(tmpPtr == NULL)\r
- return MODULE_ERR_MALLOC;\r
- gPCI_Devices = tmpPtr;\r
- \r
if(devInfo.oc == PCI_OC_PCIBRIDGE)\r
{\r
#if LIST_DEVICES\r
BusID, dev, fcn, devInfo.vendor, devInfo.device);\r
#endif\r
//TODO: Handle PCI-PCI Bridges\r
- //PCI_ScanBus( );\r
- giPCI_BusCount++;\r
+ //PCI_ScanBus(devInfo.???, bFill);\r
+ giPCI_BusCount ++;\r
}\r
else\r
{\r
#endif\r
}\r
\r
- devInfo.Node.Inode = giPCI_DeviceCount;\r
- memcpy(&gPCI_Devices[giPCI_DeviceCount], &devInfo, sizeof(tPCIDevice));\r
+ if( bFill ) {\r
+ devInfo.Node.Inode = giPCI_DeviceCount;\r
+ memcpy(&gPCI_Devices[giPCI_DeviceCount], &devInfo, sizeof(tPCIDevice));\r
+ }\r
giPCI_DeviceCount ++;\r
\r
- // WTF is this for?\r
- // Maybe bit 23 must be set for the device to be valid?\r
- // - Actually, maybe 23 means that there are sub-functions\r
- if(fcn == 0) {\r
- if( !(devInfo.ConfigCache[3] & 0x00800000) )\r
- break;\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
}\r
\r
return strdup( gPCI_Devices[Pos].Name );\r
}\r
/**\r
- * \fn tVFS_Node *PCI_FindDirRoot(tVFS_Node *node, char *filename)\r
+ * \fn tVFS_Node *PCI_FindDirRoot(tVFS_Node *node, const char *filename)\r
*/\r
-tVFS_Node *PCI_FindDirRoot(tVFS_Node *node, char *filename)\r
+tVFS_Node *PCI_FindDirRoot(tVFS_Node *node, const char *filename)\r
{\r
int bus,slot,fcn;\r
int i;\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
}\r
\r
/**\r
- * \fn int PCI_EnumDevice(Uint16 bus, Uint16 slot, Uint16 fcn, tPCIDevice *info)\r
+ * \fn int PCI_EnumDevice(Uint16 bus, Uint16 slot, Uint16 fcn, tPCIDevice *info)\r
+ * \brief Get device information for a slot/function\r
*/\r
-int PCI_EnumDevice(Uint16 bus, Uint16 slot, Uint16 fcn, tPCIDevice *info)\r
+int PCI_EnumDevice(Uint16 bus, Uint16 slot, Uint16 fcn, tPCIDevice *info)\r
{\r
Uint16 vendor;\r
int i;\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
- //Debug("PCI(0x%x) = 0x%08x", address, data);\r
- return 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 = PCI_CfgReadDWord(bus, dev, func, offset);\r
- \r
- data >>= (offset&2)*8; // Allow Access to Upper Word\r
- \r
- return (Uint16)data;\r
-}\r
-\r
-Uint8 PCI_CfgReadByte(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset)\r
-{\r
- Uint32 data = PCI_CfgReadDWord(bus, dev, func, offset);\r
- \r
- data >>= (offset&3)*8; //Allow Access to Upper Word\r
- return (Uint8)data;\r
-}\r
-\r
-\r
// === EXPORTS ===\r
//*\r
EXPORT(PCI_CountDevices);\r