?? bsl_pdev.c
字號:
/******************************************************************************\
* Copyright (C) 2004 by RTD Embedded Technologies, Inc. All rights reserved.
* Confidential and Proprietary, Not for Public Release
*------------------------------------------------------------------------------
* PROJECT.......... Board Support Library for SPM6420
* VERSION.......... (Defined in README.TXT)
*------------------------------------------------------------------------------
* CONTENT.......... PCI Device Module of BSL
* FILENAME......... bsl_pdev.c
\******************************************************************************/
#define _BSL_PDEV_MOD_
#include <bsl_pdev.h>
#include <bsl_pcibus.h>
#if (BSL_PDEV_SUPPORT)
/******************************************************************************\
* L O C A L S E C T I O N
\******************************************************************************/
/******************************************************************************\
* static macro declarations
\******************************************************************************/
// this many PCI devices can be opened at a time
#define PDEV_MAX_OPENED_PCI_DEVICES 4
// PCI config register number in a PCI device's header
#define PDEV_HDR_PCIIDR_REGOFFS32 0
#define PDEV_HDR_PCICRSR_REGOFFS32 1
#define PDEV_HDR_PCIBAR0_REGOFFS32 4
#define PDEV_HDR_PCIBAR1_REGOFFS32 5
#define PDEV_HDR_PCIBAR2_REGOFFS32 6
#define PDEV_HDR_PCIBAR3_REGOFFS32 7
/******************************************************************************\
* static typedef declarations
\******************************************************************************/
// structure to maintain the opened PCI devices
typedef struct {
Uint32 vendorAndDeviceID;
Uint32 ordinal;
} PDEV_OpenedDevices;
/******************************************************************************\
* static function declarations
\******************************************************************************/
BOOL PDEV_isOpened(Uint32 vendorAndDeviceID, Uint32 ordinal);
Uint32 PDEV_canBeOpened();
Uint32 PDEV_findDevice(Uint32 vendorAndDeviceID, Uint32 ordinal,
PDEV_DeviceObj *deviceObj);
Uint32 PDEV_readPCIcfg(Uint32 reg, Uint32 dev, Uint32 *val);
Uint32 PDEV_writePCIcfg(Uint32 reg, Uint32 dev, Uint32 val);
/******************************************************************************\
* static variable definitions
\******************************************************************************/
// stores the opened PCI devices ({0,0} means, the 'slot' is empty)
PDEV_OpenedDevices _PDEV_openedDevices[PDEV_MAX_OPENED_PCI_DEVICES] = {
{0, 0}, {0, 0}, {0, 0}, {0, 0}
};
/******************************************************************************\
* static function definitions
\******************************************************************************/
//==============================================================================
// Returns TRUE, if the given PCI device is opened currently.
//
// parameters:
// vendorAndDeviceID Vendor and Device ID of the queried PCI device.
// ordinal Ordinal number of the queried PCI device within the
// set of the same Vendor and Device ID devices.
//
// returns:
// TRUE, if the queried PCI device is opened currently.
// Otherwise, FALSE.
//==============================================================================
BOOL PDEV_isOpened(Uint32 vendorAndDeviceID, Uint32 ordinal)
{
Uint32 dev;
for( dev = 0; dev < PDEV_MAX_OPENED_PCI_DEVICES; dev++)
{
if( (_PDEV_openedDevices[dev].vendorAndDeviceID == vendorAndDeviceID)
&& (_PDEV_openedDevices[dev].ordinal == ordinal) ) return TRUE;
}
return FALSE;
}
//==============================================================================
// Returns the index of the slot that can be used to store a new opened PCI
// device for maintain.
// If there is no more room, the returned value is greater than the greatest
// index.
//==============================================================================
Uint32 PDEV_canBeOpened()
{
Uint32 dev;
for( dev = 0; dev < PDEV_MAX_OPENED_PCI_DEVICES; dev++)
{
if( (_PDEV_openedDevices[dev].vendorAndDeviceID == 0)
&& (_PDEV_openedDevices[dev].ordinal == 0) ) return dev;
}
/* there is no more place */
return (PDEV_MAX_OPENED_PCI_DEVICES + 1);
}
//==============================================================================
// Attempts to find a PCI device and fills up a PDEV_DeviceObj structure to
// handle the found device.
//
// This function can find PCI device with 'function number' 0 only.
//
// parameters:
// vendorAndDeviceID Vendor and Device ID of the queried PCI device.
// The PDEV_PCI_BOARD_RTD_x macros should be used.
// ordinal Ordinal number of the queried PCI device within the
// set of the same Vendor and Device ID devices.
// Must be at least 1.
// pDeviceObj Pointer to the PCI device descriptor to be filled
// up, if the requested device has been found.
//
// returns:
// PDEV_DEVICE_FOUND All right. Device has been found.
// PDEV_DEVICE_NOT_FOUND No error, but the device has not been found.
// PDEV_PCI_CONFIG_ERROR PCI configuration cycle error has occured.
//==============================================================================
Uint32 PDEV_findDevice(Uint32 vendorAndDeviceID, Uint32 ordinal,
PDEV_DeviceObj * pDeviceObj)
{
Uint32 dev, ven_dev_id, ord;
Uint32 pcicrsr;
Uint32 bar;
ord = 1;
for( dev = 0; dev <= 15; dev++ )
{
// read PCI Configuration and check error
if( PDEV_readPCIcfg(PDEV_HDR_PCIIDR_REGOFFS32,dev,&ven_dev_id)
== PCIBUS_TOE_NO_ERROR )
{
// a PCI device has been found
if( ven_dev_id == vendorAndDeviceID )
{
// an appropriate PCI device has been found according to the
// given Vendor and Device IDs
if( ord >= ordinal )
// the ">=" is a protection for parameter 'ordinal' = 0
// thus, the ordinal = 0 and 1 mean 1
{
// the required PCI device has been found
// stores the location of the device
// If later, a PCI config cycle has to be applied for the
// opened device, you can use this device number.
pDeviceObj->location = dev;
pDeviceObj->barTypes = 0;
// read PCICRSR reg.
if( PDEV_readPCIcfg(
PDEV_HDR_PCICRSR_REGOFFS32,dev,&pcicrsr)
!= PCIBUS_TOE_NO_ERROR )
{
return PDEV_PCI_CONFIG_ERROR;
}
// clear PCICRSR reg's error flags and set flags to
// response Memory and I/O cycles.
pcicrsr |= 0xF8000007;
// write PCICRSR reg. back
if( PDEV_writePCIcfg(
PDEV_HDR_PCICRSR_REGOFFS32,dev,pcicrsr)
!= PCIBUS_TOE_NO_ERROR )
{
return PDEV_PCI_CONFIG_ERROR;
}
// read Base Address registers
for( bar = 0; bar < PDEV_NUMBER_OF_BARS; bar++ )
{
if( PDEV_readPCIcfg(
PDEV_HDR_PCIBAR0_REGOFFS32 + bar,
dev, &(pDeviceObj->baseAddress[bar]) )
!= PCIBUS_TOE_NO_ERROR )
{
return PDEV_PCI_CONFIG_ERROR;
}
// store the Type Of the base address (Memory or I/O)
pDeviceObj->barTypes |=
(pDeviceObj->baseAddress[bar] & 0xF) << (4 * bar);
// make clear Base Address without control bits in the
// lower bits
pDeviceObj->baseAddress[bar] &= ~0xF;
}
// The requested PCI device has been found, the major
// information about the device has been stored in the
// pDeviceObj.
return PDEV_DEVICE_FOUND;
}
// search the next device with the same Vendor and Device IDs
ord++;
}
else
{
// NOT this device what we want to find
// do nothing, go on
}
}
}
// The requested PCI device has not been found.
return PDEV_DEVICE_NOT_FOUND;
}
//==============================================================================
// Initiates a PCI Configuration Read Cycle to read a PCI Configuration
// register of a PCI device.
//
// parameters:
// reg ordinal number of the register to be read
// dev PCI device number of the PCI deivce to be reached
// val pointer to an Uint32-type variable to be filled up with the
// value of the read register
//
// returns:
// error codes according to the PCIBUS_getError()
// PCIBUS_TOE_NO_ERROR = All right.
//==============================================================================
Uint32 PDEV_readPCIcfg(Uint32 reg, Uint32 dev, Uint32 *val)
{
PCIBUS_AccessReqObj reqCfgCycle;
// make a request for the PCI Configuration Cycle
PCIBUS_makeReq_Cfg(
&reqCfgCycle, reg, 0, dev, val, PCIBUS_TRANSFER_FROM_PCI);
// reading
PCIBUS_accessReqWithWait( &reqCfgCycle );
// check error
return PCIBUS_getError( &reqCfgCycle );
}
//==============================================================================
// Initiates a PCI Configuration Write Cycle to write a PCI Configuration
// register of a PCI device.
//
// parameters:
// reg ordinal number of the register to be read
// dev PCI device number of the PCI deivce to be reached
// bus PCI bus number of the PCI deivce to be reached
// val 32-bit word to be written into the selected register of the
// accessed PCI device
//
// returns:
// error codes according to the PCIBUS_getError()
// PCIBUS_TOE_NO_ERROR = All right.
//==============================================================================
Uint32 PDEV_writePCIcfg(Uint32 reg, Uint32 dev, Uint32 val)
{
PCIBUS_AccessReqObj reqCfgCycle;
Uint32 value = val;
// make a request for the PCI Configuration Cycle
PCIBUS_makeReq_Cfg(
&reqCfgCycle, reg, 0, dev, &value, PCIBUS_TRANSFER_TO_PCI);
// reading
PCIBUS_accessReqWithWait( &reqCfgCycle );
// check error
return PCIBUS_getError( &reqCfgCycle );
}
/******************************************************************************\
* G L O B A L S E C T I O N
\******************************************************************************/
/******************************************************************************\
* global variable definitions
\******************************************************************************/
/******************************************************************************\
* global function definitions
\******************************************************************************/
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -