Kernel - Added a (slightly hacky) virtual PCI interface
[tpg/acess2.git] / KernelLand / Kernel / drv / pci.c
index 702c9cc..2e1ce15 100644 (file)
@@ -1,6 +1,9 @@
 /*\r
- * AcessOS/AcessBasic v0.1\r
- * PCI Bus Driver\r
+ * Acess2 Kernel\r
+ * - By John Hodge (thePowersGang)\r
+ * \r
+ * drv/pci.c\r
+ * - PCI Enumeration and Arbitration\r
  */\r
 #define DEBUG  0\r
 #include <acess.h>\r
@@ -9,9 +12,11 @@
 #include <fs_devfs.h>\r
 #include <drv_pci.h>\r
 #include <drv_pci_int.h>\r
+#include <virtual_pci.h>\r
 \r
 #define USE_PORT_BITMAP        0\r
 #define        LIST_DEVICES    1\r
+#define PCI_MAX_BUSSES 8\r
 \r
 // === STRUCTURES ===\r
 typedef struct sPCIDevice\r
@@ -42,6 +47,7 @@ size_t        PCI_int_ReadDevice(tVFS_Node *node, off_t Offset, size_t Length, void *bu
 // === GLOBALS ===\r
 MODULE_DEFINE(0, 0x0100, PCI, PCI_Install, NULL, NULL);\r
  int   giPCI_BusCount = 1;\r
+Uint8  gaPCI_BusNumbers[PCI_MAX_BUSSES];\r
  int   giPCI_InodeHandle = -1;\r
  int   giPCI_DeviceCount = 0;\r
 tPCIDevice     *gPCI_Devices = NULL;\r
@@ -95,12 +101,18 @@ int PCI_Install(char **Arguments)
        #endif  \r
 \r
        // Scan Bus (Bus 0, Don't fill gPCI_Devices)\r
+       giPCI_DeviceCount = 0;\r
+       giPCI_BusCount = 1;\r
+       gaPCI_BusNumbers[0] = 0;\r
        for( bus = 0; bus < giPCI_BusCount; bus ++ )\r
        {\r
-               ret = PCI_ScanBus(bus, 0);\r
+               ret = PCI_ScanBus(gaPCI_BusNumbers[bus], 0);\r
                if(ret != MODULE_ERR_OK)        return ret;\r
        }\r
-               \r
+       // TODO: PCIe\r
+       // - Add VPCI Devices\r
+       giPCI_DeviceCount += giVPCI_DeviceCount;\r
+       \r
        if(giPCI_DeviceCount == 0) {\r
                Log_Notice("PCI", "No devices were found");\r
                return MODULE_ERR_NOTNEEDED;\r
@@ -123,7 +135,33 @@ int PCI_Install(char **Arguments)
        // Rescan, filling the PCI device array\r
        for( bus = 0; bus < giPCI_BusCount; bus ++ )\r
        {\r
-               PCI_ScanBus(bus, 1);\r
+               PCI_ScanBus(gaPCI_BusNumbers[bus], 1);\r
+       }\r
+       // Insert VPCI Devices\r
+       for( int i = 0; i < giVPCI_DeviceCount; i ++ )\r
+       {\r
+               tPCIDevice      *devinfo = &gPCI_Devices[giPCI_DeviceCount];\r
+               \r
+               devinfo->bus = -1;\r
+               devinfo->slot = i;\r
+               devinfo->fcn = 0;\r
+               devinfo->vendor = gaVPCI_Devices[i].Vendor;\r
+               devinfo->device = gaVPCI_Devices[i].Device;\r
+               devinfo->revision = gaVPCI_Devices[i].Class & 0xFF;\r
+               devinfo->class = gaVPCI_Devices[i].Class >> 8;\r
+               snprintf(devinfo->Name, sizeof(devinfo->Name), "%02x.%02x:%x", 0xFF, i, 0);\r
+\r
+               for(int j = 0; j < 256/4; j ++ )\r
+                       devinfo->ConfigCache[i] = VPCI_Read(&gaVPCI_Devices[i], j*4, 4);\r
+\r
+               memset(&devinfo->Node, 0, sizeof(devinfo->Node));\r
+               devinfo->Node.Inode = giPCI_DeviceCount;\r
+               devinfo->Node.Size = 256;\r
+               devinfo->Node.NumACLs = 1;\r
+               devinfo->Node.ACLs = &gVFS_ACL_EveryoneRO;\r
+               devinfo->Node.Type = &gPCI_DevNodeType;\r
+\r
+               giPCI_DeviceCount ++;\r
        }\r
        \r
        // Complete Driver Structure\r
@@ -158,26 +196,12 @@ int PCI_ScanBus(int BusID, int bFill)
                        if(!PCI_int_EnumDevice(BusID, dev, fcn, &devInfo))\r
                                continue;\r
                        \r
-                       if(devInfo.class == 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
-                               #if LIST_DEVICES\r
-                               if( !bFill )\r
-                                       Log_Log("PCI", "Device %i,%i:%i %06x => 0x%04x:0x%04x Rev %i",\r
-                                               BusID, dev, fcn, devInfo.class,\r
-                                               devInfo.vendor, devInfo.device, devInfo.revision);\r
-                               #endif\r
-                       }\r
+                       #if LIST_DEVICES\r
+                       if( !bFill )\r
+                               Log_Log("PCI", "Device %i,%i:%i %06x => 0x%04x:0x%04x Rev %i",\r
+                                       BusID, dev, fcn, devInfo.class,\r
+                                       devInfo.vendor, devInfo.device, devInfo.revision);\r
+                       #endif\r
                        \r
                        if( bFill ) {\r
                                devInfo.Node.Inode = giPCI_DeviceCount;\r
@@ -185,7 +209,28 @@ int PCI_ScanBus(int BusID, int bFill)
                        }\r
                        giPCI_DeviceCount ++;\r
                        \r
-                       // If bit 23 of (soemthing) is set, there are sub-functions\r
+                       switch(devInfo.ConfigCache[3] & 0x007F0000)\r
+                       {\r
+                       case 0x00:      // Normal device\r
+                               break;\r
+                       case 0x01:      // PCI-PCI Bridge\r
+                               {\r
+                               // TODO: Add to list of busses?\r
+                               Uint8   sec = (devInfo.ConfigCache[6] & 0x0000FF00) >> 8;\r
+                               #if LIST_DEVICES\r
+                               if( !bFill ) {\r
+                                       Uint8   pri = (devInfo.ConfigCache[6] & 0x000000FF) >> 0;\r
+                                       Log_Log("PCI", "- PCI-PCI Bridge %02x=>%02x", pri, sec);\r
+                               }\r
+                               #endif\r
+                               gaPCI_BusNumbers[giPCI_BusCount++] = sec;\r
+                               }\r
+                               break;\r
+                       case 0x02:      // PCI-CardBus Bridge\r
+                               break;\r
+                       }\r
+\r
+                       // If bit 8 of the Header Type register is set, there are sub-functions\r
                        if(fcn == 0 && !(devInfo.ConfigCache[3] & 0x00800000) )\r
                                break;\r
                }\r
@@ -212,35 +257,16 @@ int PCI_int_ReadDirRoot(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
  */\r
 tVFS_Node *PCI_int_FindDirRoot(tVFS_Node *node, const char *filename)\r
 {\r
-        int    bus,slot,fcn;\r
         int    i;\r
-       // Validate Filename (Pointer and length)\r
-       if(!filename || strlen(filename) != 7)\r
-               return NULL;\r
-       // Check for spacers\r
-       if(filename[2] != '.' || filename[5] != ':')\r
-               return NULL;\r
-       \r
-       // Get Information\r
-       if(filename[0] < '0' || filename[0] > '9')      return NULL;\r
-       bus = (filename[0] - '0')*10;\r
-       if(filename[1] < '0' || filename[1] > '9')      return NULL;\r
-       bus += filename[1] - '0';\r
-       if(filename[3] < '0' || filename[3] > '9')      return NULL;\r
-       slot = (filename[3] - '0')*10;\r
-       if(filename[4] < '0' || filename[4] > '9')      return NULL;\r
-       slot += filename[4] - '0';\r
-       if(filename[6] < '0' || filename[6] > '9')      return NULL;\r
-       fcn = filename[6] - '0';\r
        \r
        // Find Match\r
        for(i=0;i<giPCI_DeviceCount;i++)\r
        {\r
-               if(gPCI_Devices[i].bus != bus)          continue;\r
-               if(gPCI_Devices[i].slot != slot)        continue;\r
-               if(gPCI_Devices[i].fcn != fcn)  continue;\r
-               \r
-               return &gPCI_Devices[i].Node;\r
+               int cmp = strcmp(gPCI_Devices[i].Name, filename);\r
+               if( cmp > 0 )   // Sorted list\r
+                       break;\r
+               if( cmp == 0 )\r
+                       return &gPCI_Devices[i].Node;\r
        }\r
        \r
        // Error Return\r
@@ -372,6 +398,11 @@ Uint32 PCI_ConfigRead(tPCIDev ID, int Offset, int Size)
        if( Offset & (Size - 1) )       return 0;\r
 \r
        dev = &gPCI_Devices[ID];\r
+       // Detect VPCI devices\r
+       if( dev->bus == -1 ) {\r
+               return VPCI_Read(&gaVPCI_Devices[dev->slot], Offset, Size);\r
+       }\r
+\r
        addr = PCI_int_GetBusAddr(dev->bus, dev->slot, dev->fcn, Offset);\r
 \r
        dword = PCI_CfgReadDWord(addr);\r
@@ -391,10 +422,18 @@ void PCI_ConfigWrite(tPCIDev ID, int Offset, int Size, Uint32 Value)
        tPCIDevice      *dev;\r
        Uint32  dword, addr;\r
         int    shift;\r
+\r
        if( ID < 0 || ID >= giPCI_DeviceCount ) return ;\r
        if( Offset < 0 || Offset > 256 )        return ;\r
-       \r
+\r
        dev = &gPCI_Devices[ID];\r
+\r
+       // Detect VPCI devices\r
+       if( dev->bus == -1 ) {\r
+               VPCI_Write(&gaVPCI_Devices[dev->slot], Offset, Size, Value);\r
+               return ;\r
+       }\r
+\r
        addr = PCI_int_GetBusAddr(dev->bus, dev->slot, dev->fcn, Offset);\r
 \r
        if(Size != 4)\r
@@ -456,16 +495,18 @@ int PCI_int_EnumDevice(Uint16 bus, Uint16 slot, Uint16 fcn, tPCIDevice *info)
        vendor_dev = PCI_CfgReadDWord( addr );\r
        if((vendor_dev & 0xFFFF) == 0xFFFF)     // Invalid Device\r
                return 0;\r
+       \r
+       info->bus = bus;\r
+       info->slot = slot;\r
+       info->fcn = fcn;\r
 \r
+       // Read configuration\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_dev & 0xFFFF;\r
        info->device = vendor_dev >> 16;\r
        tmp = info->ConfigCache[2];\r
@@ -479,14 +520,7 @@ int PCI_int_EnumDevice(Uint16 bus, Uint16 slot, Uint16 fcn, tPCIDevice *info)
 //     #endif\r
        \r
        // Make node name\r
-       info->Name[0] = '0' + bus/10;\r
-       info->Name[1] = '0' + bus%10;\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[6] = '0' + fcn;\r
-       info->Name[7] = '\0';\r
+       snprintf(info->Name, 8, "%02x.%02x:%x", bus, slot, fcn);\r
        \r
        // Create VFS Node\r
        memset( &info->Node, 0, sizeof(tVFS_Node) );\r

UCC git Repository :: git.ucc.asn.au