Kernel/PCI - Added function to access the Command field, better BAR functions
authorJohn Hodge <[email protected]>
Fri, 12 Jul 2013 16:16:18 +0000 (00:16 +0800)
committerJohn Hodge <[email protected]>
Fri, 12 Jul 2013 16:16:18 +0000 (00:16 +0800)
- New BAR access function allows consistent sanity checking

KernelLand/Kernel/drv/pci.c
KernelLand/Kernel/include/drv_pci.h

index d3a1ebc..e926f94 100644 (file)
@@ -463,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
@@ -486,6 +497,57 @@ 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
+       ASSERT(ret);\r
+       return ret;\r
+}\r
+\r
 /**\r
  * \brief Get device information for a slot/function\r
  */\r
index 33c4a3e..1032814 100644 (file)
@@ -33,6 +33,29 @@ enum ePCIOverClasses
        PCI_OC_SCSI = 0x010000\r
 };\r
 \r
+typedef enum ePCI_BARTypes     tPCI_BARType;\r
+\r
+enum ePCI_BARTypes\r
+{\r
+       PCI_BARTYPE_IO,\r
+       PCI_BARTYPE_MEM,        // Any memory type\r
+       PCI_BARTYPE_MEMP,       // Prefetchable memory\r
+       PCI_BARTYPE_MEMNP,      // Non-prefetchable memory\r
+       PCI_BARTYPE_MEM32,      // 32-bit memory\r
+       PCI_BARTYPE_MEM64       // 64-bit memory\r
+};\r
+\r
+#define PCI_CMD_IOENABLE       (1 << 0)\r
+#define PCI_CMD_MEMENABLE      (1 << 1)\r
+#define PCI_CMD_BUSMASTER      (1 << 2)        // Device can behave as a bus master\r
+#define PCI_CMD_SPECIALCYCLES  (1 << 3)        // Can monitor 'Special Cycle' operations\r
+#define PCI_CMD_WRAINVAL       (1 << 4)        // Memory 'Write and Invalidate' can be generated\r
+#define PCI_CMD_VGAPALSNOOP    (1 << 5)        // VGA Palette Snoop enabled\r
+#define PCI_CMD_PARITYERRRESP  (1 << 6)        // Pairity Error Response (suppress PERR# generation)\r
+#define PCI_CMD_SERRENABLE     (1 << 8)        // Enable SERR# Driver\r
+#define PCI_CMD_FASTBACKBACK   (1 << 9)        // Fast Back-Back Enable\r
+#define PCI_CMD_INTDISABLE     (1 <<10)        // Disable generation of INTx# signals\r
+\r
 typedef int    tPCIDev;\r
 \r
 /**\r
@@ -54,8 +77,10 @@ extern int   PCI_GetDeviceSubsys(tPCIDev id, Uint16 *SubsystemVendor, Uint16 *Subs
 extern Uint32  PCI_ConfigRead(tPCIDev id, int Offset, int Size);\r
 extern void    PCI_ConfigWrite(tPCIDev id, int Offset, int Size, Uint32 Value);\r
 \r
+extern Uint16  PCI_SetCommand(tPCIDev id, Uint16 SBits, Uint16 CBits);\r
 extern Uint8   PCI_GetIRQ(tPCIDev id);\r
 extern Uint32  PCI_GetBAR(tPCIDev id, int BAR);\r
+extern Uint64  PCI_GetValidBAR(tPCIDev id, int BAR, tPCI_BARType BARType);\r
 //extern Uint16        PCI_AssignPort(tPCIDev id, int bar, int count);\r
 \r
 #endif\r

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