X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Fdrv%2Fpci.c;h=72342964439125bf1a1f3a0f149b72ba009a6b1f;hb=f4e3c3d24ca880fe72396b2b0fc1ca3ce506b6ff;hp=b256d369086ca6fdf89261d386b7e51ab3e78cb8;hpb=77ed20ce9d7e25654215980d0f89e63b8dd366f0;p=tpg%2Facess2.git diff --git a/Kernel/drv/pci.c b/Kernel/drv/pci.c index b256d369..72342964 100644 --- a/Kernel/drv/pci.c +++ b/Kernel/drv/pci.c @@ -3,26 +3,26 @@ * PCI Bus Driver */ #define DEBUG 0 -#include +#include +#include #include #include #include +#include #define LIST_DEVICES 1 // === STRUCTURES === -typedef struct s_pciDevice { +typedef struct sPCIDevice +{ Uint16 bus, slot, fcn; Uint16 vendor, device; - union { - struct {Uint8 class, subclass;}; - Uint16 oc; - }; - Uint16 revision; + Uint32 class; // Class:Subclass:ProgIf + Uint8 revision; Uint32 ConfigCache[256/4]; char Name[8]; tVFS_Node Node; -} t_pciDevice; +} tPCIDevice; // === CONSTANTS === #define SPACE_STEP 5 @@ -30,33 +30,20 @@ typedef struct s_pciDevice { // === PROTOTYPES === int PCI_Install(char **Arguments); -char *PCI_ReadDirRoot(tVFS_Node *node, int pos); -tVFS_Node *PCI_FindDirRoot(tVFS_Node *node, char *filename); -Uint64 PCI_ReadDevice(tVFS_Node *node, Uint64 pos, Uint64 length, void *buffer); + int PCI_ScanBus(int ID, int bFill); - int PCI_CountDevices(Uint16 vendor, Uint16 device, Uint16 fcn); - int PCI_GetDevice(Uint16 vendor, Uint16 device, Uint16 fcn, int idx); - int PCI_GetDeviceByClass(Uint16 class, Uint16 mask, int prev); -Uint8 PCI_GetIRQ(int id); -Uint32 PCI_GetBAR0(int id); -Uint32 PCI_GetBAR1(int id); -Uint32 PCI_GetBAR3(int id); -Uint32 PCI_GetBAR4(int id); -Uint32 PCI_GetBAR5(int id); -Uint16 PCI_AssignPort(int id, int bar, int count); - - int PCI_EnumDevice(Uint16 bus, Uint16 dev, Uint16 fcn, t_pciDevice *info); -Uint32 PCI_CfgReadDWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset); -void PCI_CfgWriteDWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset, Uint32 data); -Uint16 PCI_CfgReadWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset); -Uint8 PCI_CfgReadByte(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset); +char *PCI_int_ReadDirRoot(tVFS_Node *node, int pos); +tVFS_Node *PCI_int_FindDirRoot(tVFS_Node *node, const char *filename); +Uint32 PCI_int_GetBusAddr(Uint16 Bus, Uint16 Slot, Uint16 Fcn, Uint8 Offset); +Uint64 PCI_int_ReadDevice(tVFS_Node *node, Uint64 pos, Uint64 length, void *buffer); + int PCI_int_EnumDevice(Uint16 bus, Uint16 dev, Uint16 fcn, tPCIDevice *info); // === GLOBALS === -//MODULE_DEFINE(0, 0x0100, PCI, PCI_Install, NULL); +MODULE_DEFINE(0, 0x0100, PCI, PCI_Install, NULL, NULL); int giPCI_BusCount = 1; int giPCI_InodeHandle = -1; int giPCI_DeviceCount = 0; -t_pciDevice *gPCI_Devices = NULL; +tPCIDevice *gPCI_Devices = NULL; tDevFS_Driver gPCI_DriverStruct = { NULL, "pci", { @@ -64,102 +51,132 @@ tDevFS_Driver gPCI_DriverStruct = { .Size = -1, .NumACLs = 1, .ACLs = &gVFS_ACL_EveryoneRX, - .ReadDir = PCI_ReadDirRoot, - .FindDir = PCI_FindDirRoot + .ReadDir = PCI_int_ReadDirRoot, + .FindDir = PCI_int_FindDirRoot } }; - Uint32 *gaPCI_PortBitmap = NULL; +Uint32 *gaPCI_PortBitmap = NULL; +Uint32 gaPCI_BusBitmap[256/32]; // === CODE === /** - * \fn int PCI_Install() * \brief Scan the PCI Bus for devices + * \param Arguments Boot-time parameters */ int PCI_Install(char **Arguments) { - int bus, dev, fcn, i; - int space = 0; - t_pciDevice devInfo; - void *tmpPtr = NULL; + int i; + void *tmpPtr; // Build Portmap gaPCI_PortBitmap = malloc( 1 << 13 ); + if( !gaPCI_PortBitmap ) { + Log_Error("PCI", "Unable to allocate %i bytes for bitmap", 1 << 13); + return MODULE_ERR_MALLOC; + } memset( gaPCI_PortBitmap, 0, 1 << 13 ); for( i = 0; i < MAX_RESERVED_PORT / 32; i ++ ) gaPCI_PortBitmap[i] = -1; for( i = 0; i < MAX_RESERVED_PORT % 32; i ++ ) gaPCI_PortBitmap[MAX_RESERVED_PORT / 32] = 1 << i; - //LogF("Done.\n"); - // Scan Busses - for( bus = 0; bus < giPCI_BusCount; bus++ ) + // Scan Bus (Bus 0, Don't fill gPCI_Devices) + i = PCI_ScanBus(0, 0); + if(i != MODULE_ERR_OK) return i; + + if(giPCI_DeviceCount == 0) { + Log_Notice("PCI", "No devices were found"); + return MODULE_ERR_NOTNEEDED; + } + + // Allocate device buffer + tmpPtr = malloc(giPCI_DeviceCount * sizeof(tPCIDevice)); + if(tmpPtr == NULL) { + Log_Warning("PCI", "Malloc ERROR"); + return MODULE_ERR_MALLOC; + } + gPCI_Devices = tmpPtr; + + Log_Log("PCI", "%i devices, filling structure", giPCI_DeviceCount); + + // Reset counts + giPCI_DeviceCount = 0; + giPCI_BusCount = 0; + memset(gaPCI_BusBitmap, 0, sizeof(gaPCI_BusBitmap)); + // Rescan, filling the PCI device array + PCI_ScanBus(0, 1); + + // Complete Driver Structure + gPCI_DriverStruct.RootNode.Size = giPCI_DeviceCount; + + // And add to DevFS + DevFS_AddDevice(&gPCI_DriverStruct); + + return MODULE_ERR_OK; +} + +/** + * \brief Scans a specific PCI Bus + * \param BusID PCI Bus ID to scan + * \param bFill Fill the \a gPCI_Devices array? + */ +int PCI_ScanBus(int BusID, int bFill) +{ + int dev, fcn; + tPCIDevice devInfo; + + if( gaPCI_BusBitmap[BusID/32] & (1 << (BusID%32)) ) + return MODULE_ERR_OK; + + gaPCI_BusBitmap[BusID/32] |= (1 << (BusID%32)); + + for( dev = 0; dev < 32; dev++ ) // 32 Devices per bus { - for( dev = 0; dev < 10; dev++ ) // 10 Devices per bus + for( fcn = 0; fcn < 8; fcn++ ) // Max 8 functions per device { - for( fcn = 0; fcn < 8; fcn++ ) // 8 functions per device + // Check if the device/function exists + if(!PCI_int_EnumDevice(BusID, dev, fcn, &devInfo)) + continue; + + if(devInfo.class == PCI_OC_PCIBRIDGE) + { + #if LIST_DEVICES + if( !bFill ) + Log_Log("PCI", "Bridge @ %i,%i:%i (0x%x:0x%x)", + BusID, dev, fcn, devInfo.vendor, devInfo.device); + #endif + //TODO: Handle PCI-PCI Bridges + //PCI_ScanBus(devInfo.???, bFill); + giPCI_BusCount ++; + } + else { - // Check if the device/function exists - if(!PCI_EnumDevice(bus, dev, fcn, &devInfo)) - { - continue; - } - - if(giPCI_DeviceCount == space) - { - space += SPACE_STEP; - tmpPtr = realloc(gPCI_Devices, space*sizeof(t_pciDevice)); - if(tmpPtr == NULL) - break; - gPCI_Devices = tmpPtr; - } - if(devInfo.oc == PCI_OC_PCIBRIDGE) - { - #if LIST_DEVICES - Log("[PCI ] Bridge @ %i,%i:%i (0x%x:0x%x)", - bus, dev, fcn, devInfo.vendor, devInfo.device); - #endif - giPCI_BusCount++; - } - devInfo.Node.Inode = giPCI_DeviceCount; - memcpy(&gPCI_Devices[giPCI_DeviceCount], &devInfo, sizeof(t_pciDevice)); - giPCI_DeviceCount ++; #if LIST_DEVICES - Log("[PCI ] Device %i,%i:%i => 0x%x:0x%x", - bus, dev, fcn, devInfo.vendor, devInfo.device); + if( !bFill ) + Log_Log("PCI", "Device %i,%i:%i %06x => 0x%04x:0x%04x", + BusID, dev, fcn, devInfo.class, devInfo.vendor, devInfo.device); #endif - - // WTF is this for? - if(fcn == 0) { - if( !(devInfo.ConfigCache[3] & 0x800000) ) - break; - } } - if(tmpPtr != gPCI_Devices) + + if( bFill ) { + devInfo.Node.Inode = giPCI_DeviceCount; + memcpy(&gPCI_Devices[giPCI_DeviceCount], &devInfo, sizeof(tPCIDevice)); + } + giPCI_DeviceCount ++; + + // If bit 23 of (soemthing) is set, there are sub-functions + if(fcn == 0 && !(devInfo.ConfigCache[3] & 0x00800000) ) break; } - if(tmpPtr != gPCI_Devices) - break; } - tmpPtr = realloc(gPCI_Devices, giPCI_DeviceCount*sizeof(t_pciDevice)); - if(tmpPtr == NULL) - return 0; - gPCI_Devices = tmpPtr; - //LogF("Done.\n"); - - // Complete Driver Structure - gPCI_DriverStruct.RootNode.Size = giPCI_DeviceCount; - // And add to DevFS - DevFS_AddDevice(&gPCI_DriverStruct); - - return 1; + return MODULE_ERR_OK; } /** - * \fn char *PCI_ReadDirRoot(tVFS_Node *Node, int Pos) * \brief Read from Root of PCI Driver */ -char *PCI_ReadDirRoot(tVFS_Node *Node, int Pos) +char *PCI_int_ReadDirRoot(tVFS_Node *Node, int Pos) { ENTER("pNode iPos", Node, Pos); if(Pos < 0 || Pos >= giPCI_DeviceCount) { @@ -171,9 +188,8 @@ char *PCI_ReadDirRoot(tVFS_Node *Node, int Pos) return strdup( gPCI_Devices[Pos].Name ); } /** - * \fn tVFS_Node *PCI_FindDirRoot(tVFS_Node *node, char *filename) */ -tVFS_Node *PCI_FindDirRoot(tVFS_Node *node, char *filename) +tVFS_Node *PCI_int_FindDirRoot(tVFS_Node *node, const char *filename) { int bus,slot,fcn; int i; @@ -211,9 +227,8 @@ tVFS_Node *PCI_FindDirRoot(tVFS_Node *node, char *filename) } /** - * \fn Uint64 PCI_ReadDevice(tVFS_Node *node, Uint64 pos, Uint64 length, void *buffer) */ -Uint64 PCI_ReadDevice(tVFS_Node *node, Uint64 pos, Uint64 length, void *buffer) +Uint64 PCI_int_ReadDevice(tVFS_Node *node, Uint64 pos, Uint64 length, void *buffer) { if( pos + length > 256 ) return 0; @@ -227,41 +242,35 @@ Uint64 PCI_ReadDevice(tVFS_Node *node, Uint64 pos, Uint64 length, void *buffer) // --- Kernel Code Interface --- /** - \fn int PCI_CountDevices(Uint16 vendor, Uint16 device, Uint16 fcn) - \brief Counts the devices with the specified codes - \param vendor Vendor ID - \param device Device ID - \param fcn Function ID -*/ -int PCI_CountDevices(Uint16 vendor, Uint16 device, Uint16 fcn) + * \brief Counts the devices with the specified codes + * \param vendor Vendor ID + * \param device Device ID + */ +int PCI_CountDevices(Uint16 vendor, Uint16 device) { int i, ret=0; for(i=0;i= giPCI_DeviceCount) - return 0; - return gPCI_Devices[id].ConfigCache[15]; - //return PCI_CfgReadByte( gPCI_Devices[id].bus, gPCI_Devices[id].slot, gPCI_Devices[id].fcn, 0x3C); + tPCIDevice *dev = &gPCI_Devices[ID]; + if(ID < 0 || ID >= giPCI_DeviceCount) return 1; + + if(Vendor) *Vendor = dev->vendor; + if(Device) *Device = dev->device; + if(Class) *Class = dev->class; + return 0; } -/** - \fn Uint32 PCI_GetBAR0(int id) -*/ -Uint32 PCI_GetBAR0(int id) +int PCI_GetDeviceVersion(tPCIDev ID, Uint8 *Revision) { - if(id < 0 || id >= giPCI_DeviceCount) - return 0; - return gPCI_Devices[id].ConfigCache[4]; + tPCIDevice *dev = &gPCI_Devices[ID]; + if(ID < 0 || ID >= giPCI_DeviceCount) return 1; + + if(Revision) *Revision = dev->revision; + return 0; } -/** - \fn Uint32 PCI_GetBAR1(int id) -*/ -Uint32 PCI_GetBAR1(int id) +int PCI_GetDeviceSubsys(tPCIDev ID, Uint16 *SubsystemVendor, Uint16 *SubsystemID) { - if(id < 0 || id >= giPCI_DeviceCount) - return 0; - return gPCI_Devices[id].ConfigCache[5]; + tPCIDevice *dev = &gPCI_Devices[ID]; + if(ID < 0 || ID >= giPCI_DeviceCount) return 1; + + if(SubsystemVendor) *SubsystemVendor = dev->ConfigCache[0x2c/4] & 0xFFFF; + if(SubsystemID) *SubsystemID = dev->ConfigCache[0x2c/4] >> 16; + + return 0; } -/** - \fn Uint32 PCI_GetBAR2(int id) -*/ -Uint32 PCI_GetBAR2(int id) +Uint32 PCI_int_GetBusAddr(Uint16 Bus, Uint16 Slot, Uint16 Fcn, Uint8 Offset) { - if(id < 0 || id >= giPCI_DeviceCount) - return 0; - return gPCI_Devices[id].ConfigCache[6]; + Bus &= 0xFF; + Slot &= 0x1F; + Fcn &= 7; + Offset &= 0xFC; + return ((Uint32)Bus << 16) | (Slot << 11) | (Fcn << 8) | (Offset & 0xFC); } -/** - \fn Uint32 PCI_GetBAR3(int id) -*/ -Uint32 PCI_GetBAR3(int id) +Uint32 PCI_ConfigRead(tPCIDev ID, int Offset, int Size) { - if(id < 0 || id >= giPCI_DeviceCount) + tPCIDevice *dev; + Uint32 dword, addr; + + if( ID < 0 || ID >= giPCI_DeviceCount ) return 0; + if( Offset < 0 || Offset > 256 ) return 0; + + // TODO: Should I support non-aligned reads? + if( Offset & (Size - 1) ) return 0; + + dev = &gPCI_Devices[ID]; + addr = PCI_int_GetBusAddr(dev->bus, dev->slot, dev->fcn, Offset); + + dword = PCI_CfgReadDWord(addr); + gPCI_Devices[ID].ConfigCache[Offset/4] = dword; + switch( Size ) + { + case 1: return (dword >> (8 * (Offset&3))) & 0xFF; + case 2: return (dword >> (8 * (Offset&2))) & 0xFFFF; + case 4: return dword; + default: return 0; - return gPCI_Devices[id].ConfigCache[7]; + } } -/** - \fn Uint32 PCI_GetBAR4(int id) -*/ -Uint32 PCI_GetBAR4(int id) +void PCI_ConfigWrite(tPCIDev ID, int Offset, int Size, Uint32 Value) { - if(id < 0 || id >= giPCI_DeviceCount) - return 0; - return gPCI_Devices[id].ConfigCache[8]; + tPCIDevice *dev; + Uint32 dword, addr; + int shift; + if( ID < 0 || ID >= giPCI_DeviceCount ) return ; + if( Offset < 0 || Offset > 256 ) return ; + + dev = &gPCI_Devices[ID]; + addr = PCI_int_GetBusAddr(dev->bus, dev->slot, dev->fcn, Offset); + + if(Size != 4) + dword = PCI_CfgReadDWord(addr); + switch(Size) + { + case 1: + shift = (Offset&3)*8; + dword &= ~(0xFF << shift); + dword |= Value << shift; + break; + case 2: + shift = (Offset&2)*8; + dword &= ~(0xFFFF << shift); + dword |= Value << shift; + break; + case 4: + dword = Value; + break; + default: + return; + } + PCI_CfgWriteDWord(addr, dword); } /** - \fn Uint32 PCI_GetBAR5(int id) -*/ -Uint32 PCI_GetBAR5(int id) + * \brief Get the IRQ assigned to a device + */ +Uint8 PCI_GetIRQ(tPCIDev id) { if(id < 0 || id >= giPCI_DeviceCount) return 0; - return gPCI_Devices[id].ConfigCache[9]; + return gPCI_Devices[id].ConfigCache[15] & 0xFF; + //return PCI_CfgReadByte( gPCI_Devices[id].bus, gPCI_Devices[id].slot, gPCI_Devices[id].fcn, 0x3C); } -Uint16 PCI_AssignPort(int id, int bar, int count) +/** + * \brief Read the a BAR (base address register) from the PCI config space + */ +Uint32 PCI_GetBAR(tPCIDev id, int BARNum) { - Uint16 portVals; - int gran=0; - int i, j; - t_pciDevice *dev; - - //LogF("PCI_AssignPort: (id=%i,bar=%i,count=%i)\n", id, bar, count); - - if(id < 0 || id >= giPCI_DeviceCount) return 0; - if(bar < 0 || bar > 5) return 0; - - dev = &gPCI_Devices[id]; - - PCI_CfgWriteDWord( dev->bus, dev->slot, dev->fcn, 0x10+bar*4, -1 ); - portVals = PCI_CfgReadDWord( dev->bus, dev->slot, dev->fcn, 0x10+bar*4 ); - dev->ConfigCache[4+bar] = portVals; - //LogF(" PCI_AssignPort: portVals = 0x%x\n", portVals); - - // Check for IO port - if( !(portVals & 1) ) return 0; - - // Mask out final bit - portVals &= ~1; - - // Get Granuality - __asm__ __volatile__ ("bsf %%eax, %%ecx" : "=c" (gran) : "a" (portVals) ); - gran = 1 << gran; - //LogF(" PCI_AssignPort: gran = 0x%x\n", gran); - - // Find free space - portVals = 0; - for( i = 0; i < 1<<16; i += gran ) - { - for( j = 0; j < count; j ++ ) - { - if( gaPCI_PortBitmap[ (i+j)>>5 ] & 1 << ((i+j)&0x1F) ) - break; - } - if(j == count) { - portVals = i; - break; - } - } - - if(portVals) - { - for( j = 0; j < count; j ++ ) - { - if( gaPCI_PortBitmap[ (portVals+j)>>5 ] |= 1 << ((portVals+j)&0x1F) ) - break; - } - PCI_CfgWriteDWord( dev->bus, dev->slot, dev->fcn, 0x10+bar*4, portVals|1 ); - dev->ConfigCache[4+bar] = portVals|1; - } - - // Return - //LogF("PCI_AssignPort: RETURN 0x%x\n", portVals); - return portVals; + if(id < 0 || id >= giPCI_DeviceCount) + return 0; + if(BARNum < 0 || BARNum >= 6) + return 0; + return gPCI_Devices[id].ConfigCache[4+BARNum]; } /** - * \fn int PCI_EnumDevice(Uint16 bus, Uint16 slot, Uint16 fcn, t_pciDevice *info) + * \brief Get device information for a slot/function */ -int PCI_EnumDevice(Uint16 bus, Uint16 slot, Uint16 fcn, t_pciDevice *info) +int PCI_int_EnumDevice(Uint16 bus, Uint16 slot, Uint16 fcn, tPCIDevice *info) { - Uint16 vendor; + Uint32 vendor_dev, tmp; int i; Uint32 addr; - - vendor = PCI_CfgReadWord(bus, slot, fcn, 0x0|0); - if(vendor == 0xFFFF) // Invalid Device + addr = PCI_int_GetBusAddr(bus, slot, fcn, 0); + + vendor_dev = PCI_CfgReadDWord( addr ); + if((vendor_dev & 0xFFFF) == 0xFFFF) // Invalid Device return 0; - + + info->ConfigCache[0] = vendor_dev; + for( i = 1, addr += 4; i < 256/4; i ++, addr += 4 ) + { + info->ConfigCache[i] = PCI_CfgReadDWord(addr); + } + info->bus = bus; info->slot = slot; info->fcn = fcn; - info->vendor = vendor; - info->device = PCI_CfgReadWord(bus, slot, fcn, 0x0|2); - info->revision = PCI_CfgReadWord(bus, slot, fcn, 0x8|0); - info->oc = PCI_CfgReadWord(bus, slot, fcn, 0x8|2); - - // Load Config Bytes - addr = 0x80000000 | ((Uint)bus<<16) | ((Uint)slot<<11) | ((Uint)fcn<<8); - for(i=0;i<256/4;i++) - { - #if 1 - outd(0xCF8, addr); - info->ConfigCache[i] = ind(0xCFC); - addr += 4; - #else - info->ConfigCache[i] = PCI_CfgReadDWord(bus, slot, fcn, i*4); - #endif - } - - //#if LIST_DEVICES - //Log("BAR0 0x%08x BAR1 0x%08x BAR2 0x%08x", info->ConfigCache[4], info->ConfigCache[5], info->ConfigCache[6]); - //Log("BAR3 0x%08x BAR4 0x%08x BAR5 0x%08x", info->ConfigCache[7], info->ConfigCache[8], info->ConfigCache[9]); - //Log("Class: 0x%04x", info->oc); - //#endif + info->vendor = vendor_dev & 0xFFFF; + info->device = vendor_dev >> 16; + tmp = info->ConfigCache[2]; + info->revision = tmp & 0xFF; + info->class = tmp >> 8; + +// #if LIST_DEVICES +// Log("BAR0 0x%08x BAR1 0x%08x BAR2 0x%08x", info->ConfigCache[4], info->ConfigCache[5], info->ConfigCache[6]); +// Log("BAR3 0x%08x BAR4 0x%08x BAR5 0x%08x", info->ConfigCache[7], info->ConfigCache[8], info->ConfigCache[9]); +// Log("Class: 0x%06x", info->class); +// #endif // Make node name info->Name[0] = '0' + bus/10; @@ -479,84 +473,20 @@ int PCI_EnumDevice(Uint16 bus, Uint16 slot, Uint16 fcn, t_pciDevice *info) info->Node.NumACLs = 1; info->Node.ACLs = &gVFS_ACL_EveryoneRO; - info->Node.Read = PCI_ReadDevice; + info->Node.Read = PCI_int_ReadDevice; return 1; } -Uint32 PCI_CfgReadDWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset) -{ - Uint32 address; - Uint32 data; - - bus &= 0xFF; // 8 Bits - dev &= 0x1F; // 5 Bits - func &= 0x7; // 3 Bits - offset &= 0xFF; // 8 Bits - - address = 0x80000000 | ((Uint)bus<<16) | ((Uint)dev<<11) | ((Uint)func<<8) | (offset&0xFC); - outd(0xCF8, address); - - data = ind(0xCFC); - return (Uint32)data; -} -void PCI_CfgWriteDWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset, Uint32 data) -{ - Uint32 address; - - bus &= 0xFF; // 8 Bits - dev &= 0x1F; // 5 Bits - func &= 0x7; // 3 Bits - offset &= 0xFF; // 8 Bits - - address = 0x80000000 | ((Uint)bus<<16) | ((Uint)dev<<11) | ((Uint)func<<8) | (offset&0xFC); - outd(0xCF8, address); - outd(0xCFC, data); -} -Uint16 PCI_CfgReadWord(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset) -{ - Uint32 data; - - bus &= 0xFF; // 8 Bits - dev &= 0x1F; // 5 Bits - func &= 0x7; // 3 Bits - offset &= 0xFF; // 8 Bits - - //LogF("PCI_CfgReadWord: (bus=0x%x,dev=0x%x,func=%x,offset=0x%x)\n", bus, dev, func, offset); - - outd(0xCF8, - 0x80000000 | ((Uint)bus<<16) | ((Uint)dev<<11) | ((Uint)func<<8) | (offset&0xFC) ); - - data = ind(0xCFC); - data >>= (offset&2)*8; //Allow Access to Upper Word - //LogF("PCI_CfgReadWord: RETURN 0x%x\n", data&0xFFFF); - return (Uint16)data; -} - -Uint8 PCI_CfgReadByte(Uint16 bus, Uint16 dev, Uint16 func, Uint16 offset) -{ - Uint32 address; - Uint32 data; - - bus &= 0xFF; // 8 Bits - dev &= 0x1F; // 4 Bits - func &= 0x7; // 3 Bits - offset &= 0xFF; // 8 Bits - - address = 0x80000000 | ((Uint)bus<<16) | ((Uint)dev<<11) | ((Uint)func<<8) | (offset&0xFC); - outd(0xCF8, address); - - data = ind(0xCFC); - data >>= (offset&3)*8; //Allow Access to Upper Word - return (Uint8)data; -} - - // === EXPORTS === //* EXPORT(PCI_CountDevices); EXPORT(PCI_GetDevice); EXPORT(PCI_GetDeviceByClass); -EXPORT(PCI_AssignPort); +EXPORT(PCI_GetDeviceInfo); +EXPORT(PCI_GetDeviceVersion); +EXPORT(PCI_GetDeviceSubsys); +//EXPORT(PCI_AssignPort); +EXPORT(PCI_GetBAR); EXPORT(PCI_GetIRQ); //*/