X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FKernel%2Fdrv%2Fpci.c;h=3a4ec865191cae3a85cfc93e787832e75e0c25b4;hb=2a17e7ae7dab0ac8ba8c434bc3b409f20d378e46;hp=2e1ce151963074bd3ff775122aca4963ca784458;hpb=04a050f42807686dc119838c82372409246d55bb;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/drv/pci.c b/KernelLand/Kernel/drv/pci.c index 2e1ce151..3a4ec865 100644 --- a/KernelLand/Kernel/drv/pci.c +++ b/KernelLand/Kernel/drv/pci.c @@ -39,9 +39,9 @@ typedef struct sPCIDevice int PCI_ScanBus(int ID, int bFill); int PCI_int_ReadDirRoot(tVFS_Node *node, int pos, char Dest[FILENAME_MAX]); -tVFS_Node *PCI_int_FindDirRoot(tVFS_Node *node, const char *filename); +tVFS_Node *PCI_int_FindDirRoot(tVFS_Node *node, const char *filename, Uint Flags); Uint32 PCI_int_GetBusAddr(Uint16 Bus, Uint16 Slot, Uint16 Fcn, Uint8 Offset); -size_t PCI_int_ReadDevice(tVFS_Node *node, off_t Offset, size_t Length, void *buffer); +size_t PCI_int_ReadDevice(tVFS_Node *node, off_t Offset, size_t Length, void *buffer, Uint Flags); int PCI_int_EnumDevice(Uint16 bus, Uint16 dev, Uint16 fcn, tPCIDevice *info); // === GLOBALS === @@ -150,9 +150,15 @@ int PCI_Install(char **Arguments) devinfo->revision = gaVPCI_Devices[i].Class & 0xFF; devinfo->class = gaVPCI_Devices[i].Class >> 8; snprintf(devinfo->Name, sizeof(devinfo->Name), "%02x.%02x:%x", 0xFF, i, 0); + + #if LIST_DEVICES + Log_Log("PCI", "Device %i,%i:%i %06x => 0x%04x:0x%04x Rev %i", + 0xFF, i, 0, devinfo->class, + devinfo->vendor, devinfo->device, devinfo->revision); + #endif for(int j = 0; j < 256/4; j ++ ) - devinfo->ConfigCache[i] = VPCI_Read(&gaVPCI_Devices[i], j*4, 4); + devinfo->ConfigCache[j] = VPCI_Read(&gaVPCI_Devices[i], j*4, 4); memset(&devinfo->Node, 0, sizeof(devinfo->Node)); devinfo->Node.Inode = giPCI_DeviceCount; @@ -209,7 +215,7 @@ int PCI_ScanBus(int BusID, int bFill) } giPCI_DeviceCount ++; - switch(devInfo.ConfigCache[3] & 0x007F0000) + switch( (devInfo.ConfigCache[3] >> 16) & 0x7F ) { case 0x00: // Normal device break; @@ -255,12 +261,10 @@ int PCI_int_ReadDirRoot(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]) } /** */ -tVFS_Node *PCI_int_FindDirRoot(tVFS_Node *node, const char *filename) +tVFS_Node *PCI_int_FindDirRoot(tVFS_Node *node, const char *filename, Uint Flags) { - int i; - // Find Match - for(i=0;i 0 ) // Sorted list @@ -276,7 +280,7 @@ tVFS_Node *PCI_int_FindDirRoot(tVFS_Node *node, const char *filename) /** * \brief Read the PCI configuration space of a device */ -size_t PCI_int_ReadDevice(tVFS_Node *node, off_t pos, size_t length, void *buffer) +size_t PCI_int_ReadDevice(tVFS_Node *node, off_t pos, size_t length, void *buffer, Uint Flags) { if( pos + length > 256 ) return 0; @@ -459,6 +463,17 @@ void PCI_ConfigWrite(tPCIDev ID, int Offset, int Size, Uint32 Value) PCI_CfgWriteDWord(addr, dword); } +Uint16 PCI_SetCommand(tPCIDev id, Uint16 SBits, Uint16 CBits) +{ + tPCIDevice *dev = &gPCI_Devices[id]; + dev->ConfigCache[1] &= ~CBits; + dev->ConfigCache[1] |= SBits; + Uint32 addr = PCI_int_GetBusAddr(dev->bus, dev->slot, dev->fcn, 1*4); + PCI_CfgWriteDWord(addr, dev->ConfigCache[1]); + dev->ConfigCache[1] = PCI_CfgReadDWord(addr); + return dev->ConfigCache[1]; +} + /** * \brief Get the IRQ assigned to a device */ @@ -482,6 +497,61 @@ Uint32 PCI_GetBAR(tPCIDev id, int BARNum) return gPCI_Devices[id].ConfigCache[4+BARNum]; } +/** + */ +Uint64 PCI_GetValidBAR(tPCIDev ID, int BARNum, tPCI_BARType Type) +{ + if( ID < 0 || ID >= giPCI_DeviceCount ) + return 0; + if( BARNum < 0 || BARNum >= 6 ) + return 0; + tPCIDevice *dev = &gPCI_Devices[ID]; + Uint32 bar_val = dev->ConfigCache[4+BARNum]; + Uint64 ret = -1; + switch( Type ) + { + case PCI_BARTYPE_IO: + if( !(bar_val & 1) ) + return 0; + ret = bar_val & ~3; + break; + + case PCI_BARTYPE_MEMNP: + if( bar_val & 8 ) return 0; + if(0) + case PCI_BARTYPE_MEMP: + if( !(bar_val & 8) ) return 0; + case PCI_BARTYPE_MEM: + if( bar_val & 1 ) return 0; + if( (bar_val & 6) == 4 ) { + ASSERTCR(BARNum, <, 5, 0); + ret = (bar_val & ~0xF) | ((Uint64)dev->ConfigCache[4+BARNum+1] << 32); + } + else { + ret = bar_val & ~0xF; + } + break; + case PCI_BARTYPE_MEM32: + if( bar_val & 1 ) return 0; + if( (bar_val & 6) != 0 ) return 0; + ret = bar_val & ~0xF; + break; + case PCI_BARTYPE_MEM64: + if( bar_val & 1 ) return 0; + if( (bar_val & 6) != 4 ) return 0; + ASSERTCR(BARNum, <, 5, 0); + ret = (bar_val & ~0xF) | ((Uint64)dev->ConfigCache[4+BARNum+1] << 32); + break; + } + ASSERT(ret != -1); + if( ret == 0 ) { + Log_Error("PCI", "PCI%i BAR%i correct type, but unallocated (0x%x)", + ID, BARNum, bar_val); + return 0; + } + return ret; +} + /** * \brief Get device information for a slot/function */