Kernel/pci - Catch non-assigned BARs with an error
[tpg/acess2.git] / KernelLand / Kernel / drv / pci.c
index 1df421e..3a4ec86 100644 (file)
@@ -39,9 +39,9 @@ typedef struct sPCIDevice
  int   PCI_ScanBus(int ID, int bFill);\r
  \r
  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
+tVFS_Node      *PCI_int_FindDirRoot(tVFS_Node *node, const char *filename, Uint Flags);\r
 Uint32 PCI_int_GetBusAddr(Uint16 Bus, Uint16 Slot, Uint16 Fcn, Uint8 Offset);\r
-size_t PCI_int_ReadDevice(tVFS_Node *node, off_t Offset, size_t Length, void *buffer);\r
+size_t PCI_int_ReadDevice(tVFS_Node *node, off_t Offset, size_t Length, void *buffer, Uint Flags);\r
  int   PCI_int_EnumDevice(Uint16 bus, Uint16 dev, Uint16 fcn, tPCIDevice *info);\r
 \r
 // === GLOBALS ===\r
@@ -215,7 +215,7 @@ int PCI_ScanBus(int BusID, int bFill)
                        }\r
                        giPCI_DeviceCount ++;\r
                        \r
-                       switch(devInfo.ConfigCache[3] & 0x007F0000)\r
+                       switch( (devInfo.ConfigCache[3] >> 16) & 0x7F )\r
                        {\r
                        case 0x00:      // Normal device\r
                                break;\r
@@ -261,12 +261,10 @@ int PCI_int_ReadDirRoot(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
 }\r
 /**\r
  */\r
-tVFS_Node *PCI_int_FindDirRoot(tVFS_Node *node, const char *filename)\r
+tVFS_Node *PCI_int_FindDirRoot(tVFS_Node *node, const char *filename, Uint Flags)\r
 {\r
-        int    i;\r
-       \r
        // Find Match\r
-       for(i=0;i<giPCI_DeviceCount;i++)\r
+       for( int i = 0; i < giPCI_DeviceCount; i ++ )\r
        {\r
                int cmp = strcmp(gPCI_Devices[i].Name, filename);\r
                if( cmp > 0 )   // Sorted list\r
@@ -282,7 +280,7 @@ tVFS_Node *PCI_int_FindDirRoot(tVFS_Node *node, const char *filename)
 /**\r
  * \brief Read the PCI configuration space of a device\r
  */\r
-size_t PCI_int_ReadDevice(tVFS_Node *node, off_t pos, size_t length, void *buffer)\r
+size_t PCI_int_ReadDevice(tVFS_Node *node, off_t pos, size_t length, void *buffer, Uint Flags)\r
 {      \r
        if( pos + length > 256 )        return 0;\r
        \r
@@ -465,6 +463,17 @@ void PCI_ConfigWrite(tPCIDev ID, int Offset, int Size, Uint32 Value)
        PCI_CfgWriteDWord(addr, dword);\r
 }\r
 \r
+Uint16 PCI_SetCommand(tPCIDev id, Uint16 SBits, Uint16 CBits)\r
+{\r
+       tPCIDevice      *dev = &gPCI_Devices[id];\r
+       dev->ConfigCache[1] &= ~CBits;\r
+       dev->ConfigCache[1] |= SBits;\r
+       Uint32 addr = PCI_int_GetBusAddr(dev->bus, dev->slot, dev->fcn, 1*4);\r
+       PCI_CfgWriteDWord(addr, dev->ConfigCache[1]);\r
+       dev->ConfigCache[1] = PCI_CfgReadDWord(addr);\r
+       return dev->ConfigCache[1];\r
+}\r
+\r
 /**\r
  * \brief Get the IRQ assigned to a device\r
  */\r
@@ -488,6 +497,61 @@ Uint32 PCI_GetBAR(tPCIDev id, int BARNum)
        return gPCI_Devices[id].ConfigCache[4+BARNum];\r
 }\r
 \r
+/**\r
+ */\r
+Uint64 PCI_GetValidBAR(tPCIDev ID, int BARNum, tPCI_BARType Type)\r
+{\r
+       if( ID < 0 || ID >= giPCI_DeviceCount )\r
+               return 0;\r
+       if( BARNum < 0 || BARNum >= 6 )\r
+               return 0;\r
+       tPCIDevice      *dev = &gPCI_Devices[ID];\r
+       Uint32  bar_val = dev->ConfigCache[4+BARNum];\r
+       Uint64  ret = -1;\r
+       switch( Type )\r
+       {\r
+       case PCI_BARTYPE_IO:\r
+               if( !(bar_val & 1) )\r
+                       return 0;\r
+               ret = bar_val & ~3;\r
+               break;\r
+\r
+       case PCI_BARTYPE_MEMNP:\r
+               if( bar_val & 8 )       return 0;\r
+               if(0)   \r
+       case PCI_BARTYPE_MEMP:\r
+               if( !(bar_val & 8) )    return 0;\r
+       case PCI_BARTYPE_MEM:\r
+               if( bar_val & 1 )       return 0;\r
+               if( (bar_val & 6) == 4 ) {\r
+                       ASSERTCR(BARNum, <, 5, 0);\r
+                       ret = (bar_val & ~0xF) | ((Uint64)dev->ConfigCache[4+BARNum+1] << 32);\r
+               }\r
+               else {\r
+                       ret = bar_val & ~0xF;\r
+               }\r
+               break;\r
+       case PCI_BARTYPE_MEM32:\r
+               if( bar_val & 1 )       return 0;\r
+               if( (bar_val & 6) != 0 )        return 0;\r
+               ret = bar_val & ~0xF;\r
+               break;\r
+       case PCI_BARTYPE_MEM64:\r
+               if( bar_val & 1 )       return 0;\r
+               if( (bar_val & 6) != 4 )        return 0;\r
+               ASSERTCR(BARNum, <, 5, 0);\r
+               ret = (bar_val & ~0xF) | ((Uint64)dev->ConfigCache[4+BARNum+1] << 32);\r
+               break;\r
+       }\r
+       ASSERT(ret != -1);\r
+       if( ret == 0 ) {\r
+               Log_Error("PCI", "PCI%i BAR%i correct type, but unallocated (0x%x)",\r
+                       ID, BARNum, bar_val);\r
+               return 0;\r
+       }\r
+       return ret;\r
+}\r
+\r
 /**\r
  * \brief Get device information for a slot/function\r
  */\r

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