📄 vxpci.cpp
字号:
{
if( vx_pci_probe_devices( pci_DrvTable, pDev ) < 0 )
{
PCI_DEBUG_PRINT( "Error probing pci device\n");
return ERR0R_GEN_FAIL_vx;
}
pDev = (pci_dev *)pDev->global_list.next;
}
return SUCCESS_vx;
}
/* -------------------------------------------------------
Function : vx_pci_scan_bus
Scans the PCI bus to find devices.
Allocates a pci_dev structure for each device found and
places in the linked list
*/
int vx_pci_scan_bus( void )
{
int deviceNo;
int devices;
ushort_t vendorId;
ushort_t deviceId;
union
{
int classCode;
unsigned char array[4];
} u;
int busNo = 0;
pci_dev *pDev;
if (pciConfigLibInit (PCI_MECHANISM_1, 0xCF8, 0xCFC, 0) != OK)
{
PCI_DEBUG_PRINT("PCI lib config error\n");
return (ERR0R_GEN_FAIL_vx);
}
devices = 0x1f;
PCI_DEBUG_PRINT("Bus #, Device#, vendorID, deviceID, u.classCode\n");
for (deviceNo=0; deviceNo < devices; deviceNo++)
{
pciConfigInWord (busNo, deviceNo, 0, PCI_CFG_VENDOR_ID, &vendorId);
pciConfigInWord (busNo, deviceNo, 0, PCI_CFG_DEVICE_ID, &deviceId);
pciConfigInByte (busNo, deviceNo, 0, PCI_CFG_PROGRAMMING_IF,
&u.array[3]);
pciConfigInByte (busNo, deviceNo, 0, PCI_CFG_SUBCLASS, &u.array[2]);
pciConfigInByte (busNo, deviceNo, 0, PCI_CFG_CLASS, &u.array[1]);
u.array[0] = 0;
if (vendorId != 0xffff)
{
PCI_DEBUG_PRINT ("%.8x %.8x %.8x %.8x %.8x %.8x\n",
busNo, deviceNo, 0, vendorId, deviceId, u.classCode);
if( ( pDev = vx_pci_find_pci_dev( busNo, deviceNo, 0 ) ) != NULL )
{
PCI_DEBUG_PRINT( "device already found on this bus, device #\n" );
}
else
{
if( (pDev = vx_pci_alloc_new_pci_dev( busNo )) == NULL )
{
return ERR0R_GEN_FAIL_vx;
}
}
pDev->bus = (pci_bus *) &pci_Bus0Struct;
pDev->device = deviceId;
pDev->devfn = PCI_DEVFN( deviceNo, 0 );
pDev->vendor = vendorId;
}
/* fill in the PCI dev structure with the values found on the bus */
}
return (SUCCESS_vx);
}
/* -------------------------------------------------------
Function : vx_pci_probe_id_table_match
Looks for a match in the pci_device_id null termated table
specified by a driver funtion. If a match is found, returns a pointer
to the table ID entry.
*/
pci_device_id *vx_pci_probe_id_table_match(const pci_device_id *pTableStart, pci_dev *pci )
{
pci_device_id *pTableEntry;
pTableEntry = (pci_device_id *)pTableStart;
while( pTableEntry->device ) /* look for null-terminated end of table */
{
if( pTableEntry->device == pci->device &&
pTableEntry->vendor == pci->vendor )
{
return pTableEntry;
}
pTableEntry++; /* go to the next table entry */
}
/* no match found in the table */
return NULL;
}
/* -------------------------------------------------------
Function : vx_pci_probe_devices
Attempts to match a pci_dev structure with and entry in the
passed driver table. If a match is found, resources are allocated,
the probe function and driver functions are called.
*/
static int vx_pci_probe_devices( const pci_driver *pPCIDrvTable[], pci_dev *pci )
{
pci_driver *pDriverTable;
pci_device_id *pIDTableEntry;
int err;
int index=0;
pDriverTable = (pci_driver *)pPCIDrvTable[index]; /* get the address of the first table */
while( pDriverTable )
{
if( ( pIDTableEntry = vx_pci_probe_id_table_match( pDriverTable->id_table, pci ) ) != 0 )
{
PCI_DEBUG_PRINT( "Found Matching PCI ID Device %s:\n", pDriverTable->name );
strcpy( pci->pretty_name, pDriverTable->name );
if( ( err = pci_enable_device_bars_vx( pci ) < 0 ) ) /* enable bar's for this device */
{
PCI_DEBUG_PRINT( "Error %d when configuring pci BAR\n", err );
return ERR0R_GEN_FAIL_vx;
}
if( ( err = ( *pDriverTable->probe )( pci, pIDTableEntry ) ) < 0 )
{
PCI_DEBUG_PRINT( "Error: probe failed for device with error %d\n", err );
return ERR0R_GEN_FAIL_vx;
}
if ( ( err = ( ( *pDriverTable->vx_start_driver ) ( pci ) )) < 0 )
{
PCI_DEBUG_PRINT( "Error: driver start failed for device with error %d\n", err );
return ERR0R_GEN_FAIL_vx;
}
}
pDriverTable = (pci_driver *)pPCIDrvTable[++index]; // set the next probe table entry
}
return SUCCESS_vx;
}
/* -------------------------------------------------------
Function : vx_pci_start
A command-line function which can be used to start all PCI drivers
*/
int vx_pci_start( void )
{
int err;
if( ( err = vx_pci_scan_bus() ) < 0 )
{
return err;
}
return vx_pci_probe_all_recognized_devices();
}
/* -------------------------------------------------------
Function : vx_pci_stop
A command-line function which can be used to stop all PCI drivers
*/
void vx_pci_stop( void )
{
pci_dev *pDev;
int count = 0;
/* re-start the memory allocation from the start of alloc space */
pci_memAllocRegionStart = PCI_SYSTEM_START_MEM_ALLOC_SPACE;
pci_IOAllocRegionStart = PCI_SYSTEM_START_IO_ALLOC_SPACE;
pDev = pci_pListHeadDev;
while( pDev )
{
vx_pci_remove_pci_dev( pDev );
pDev = pci_pListHeadDev;
count++;
};
PCI_DEBUG_PRINT( "vx_pci_remove_all_devices: %d devices removed\n",count );
}
/* -------------------------------------------------------
Function : vx_pci_free_irq
A function to disconnect the PCI IRQ number passed. Used
for un-installing drivers
*/
int vx_pci_free_irq( int irqnum, VOIDFUNCPTR funcptr )
{
printf("Freeing IRQ %d",irqnum );
sysIntDisablePIC( irqnum );
pciIntDisconnect( ( INUM_TO_IVEC ( irqnum+INT_NUM_IRQ0 ) ), funcptr );
return 0;
}
/* -------------------------------------------------------
Function : vx_pci_request_irq
A function to request a PCI IRQ based on the number passed and
connect it to the passed function. The param value will be passed
to the function when the interrupt is serviced.
Call vx_pci_free_irq to free this IRQ when no longer in use
*/
int vx_pci_request_irq( int irqnum, VOIDFUNCPTR funcptr, int param )
{
printf( "Hooking interrupt %d with param 0x%x\n",irqnum,param );
if( pciIntConnect(( INUM_TO_IVEC ( irqnum+INT_NUM_IRQ0 ) ), funcptr, param ) == OK )
{
printf( "Enabling interrupt %d\n",irqnum );
if( sysIntEnablePIC(irqnum) == OK )
{
return 0;
}
}
return -1;
}
/* -------------------------------------------------------
Function : vx_pci_get_next_dma_mem_space_align
Allocates a memory space (aligned buffer) of the passed size
for PCI DMA purposes.
Free this buffer with free() when no longer in use
*/
void *vx_pci_get_next_dma_mem_space_align( uint32 size )
{
return valloc( size );
}
/* -------------------------------------------------------
Function : d_vxpci_display
A debug function which prints out data describing which devices were
found on the bus
*/
void d_vxpci_display( void )
{
pci_dev *pDev;
int device=0;
pDev = pci_pListHeadDev;
printf("PCI Device List\n#\tName\n");
while( pDev )
{
printf( "%d:", device );
if( strlen(pDev->pretty_name) )
{
printf( " %s\n", pDev->pretty_name );
}
else
{
printf( " Unknown \n" );
}
pDev = (pci_dev *)pDev->global_list.next;
device++;
}
if( device == 0 )
{
printf("No devices found\n");
}
}
/* -------------------------------------------------------
Function : d_vxpci_set
A function to set PCI registers for a specific device. The req_device
value may be found by calling d_vxpci_display.
*/
int d_vxpci_set( int req_device, int reg, uint32 val, unsigned char numbytes)
{
int device=0;
unsigned char byte;
pci_dev *pDev;
pDev = pci_pListHeadDev;
while( pDev )
{
if( device == req_device )
{
break;
}
pDev = (pci_dev *)pDev->global_list.next;
device++;
}
if( pDev )
{
switch(numbytes)
{
case 4:
pci_write_config_dword( pDev, reg, val );
break;
case 2:
pci_write_config_word( pDev, reg, (uint16)val );
break;
default:
pci_write_config_byte( pDev, reg, (uint8)val );
break;
}
pci_write_config_byte( pDev, reg, val );
printf("Device %s\n Set Reg: 0x%x = 0x%x\n",pDev->pretty_name, reg, val );
d_vxpci_get( req_device, reg, numbytes );
}
else
{
printf("Error: Unknown device\n");
printf("Device list:\n");
d_vxpci_display();
}
return 0;
}
/* -------------------------------------------------------
Function : d_vxpci_get
A debug function to do a PCI register read for the reqested
number of bytes. Returns the register value and prints on the
shell.
For req_device values, use d_vxpci_display
*/
int d_vxpci_get( int req_device, int reg, unsigned char numbytes )
{
int device=0;
uint32 dword;
uint16 word;
uint8 byte;
pci_dev *pDev;
pDev = pci_pListHeadDev;
while( pDev )
{
if( device == req_device )
{
break;
}
pDev = (pci_dev *)pDev->global_list.next;
device++;
}
if( pDev )
{
switch(numbytes)
{
case 4:
pci_read_config_dword( pDev, reg, &dword );
break;
case 2:
pci_read_config_word( pDev, reg, &word );
dword = word;
break;
default:
pci_read_config_byte( pDev, reg, &byte );
dword = byte;
break;
}
printf("Device %s\n Read Reg: 0x%x = 0x%x\n",pDev->pretty_name, reg, dword );
}
else
{
printf("Error: Unknown device\n");
printf("Device list:\n");
d_vxpci_display();
}
return dword;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -