한 걸음씩..

[PCI] 0x0CF8, 0x0CFC 레지스터 사용 본문

프로그래밍

[PCI] 0x0CF8, 0x0CFC 레지스터 사용

반엘 2013. 7. 15. 10:53

PCI Bridge의 특정 register를 수정할 때 사용하였음..

PCI_COMMON_CONFIG를 사용한 방법으로 변경이 되지 않아 아래와 같은 방법을 사용


1. 사용 구조체


#pragma pack(1)

typedef struct _CONFIG_DATA_CHECK

{

        union 

        {

               struct  

               {

                       int     UnUse0 : 1;

                       int     UnUse1 : 1;

                       int     RegisterNumber : 6;

                       int     FunctionNumber : 3;

                       int     DeviceNumber : 5;

                       int     BusNumber : 8;

                       int     Reserved : 7;

                       int     EnableBit : 1;

               } nDataBit;

               ULONG   nData;

        } u;

} CONFIG_DATA_CHECK, *PCONFIG_DATA_CHECK;


typedef struct _PCI_DEVICE_NUMBER_INFO

{

ULONG nBus;

ULONG nDevice;

ULONG nFunction;

ULONG nMemory;

} PCI_DEVICE_NUMBER_INFO, *PPCI_DEVICE_NUMBER_INFO;

#pragma pack()


2. Source 

PPCI_DEVICE_NUMBER_INFO pDeviceNumberInfo = NULL;

CONFIG_DATA_CHECK ConfigAddressData = { 0, };


//모든 PCI 장치들이 공통적으로 사용하는 Port. 

//Read/Write명령어를 보낼 수 있다.

ULONG ConfigAddress   = 0x0CF8;


//0x0CF8번지에서 보낸 명령어 (R / W )의 결과.

ULONG ConfigData        = 0x0CFC;

ULONG nData            = 0;


// IN

pDeviceNumberInfo = (PPCI_DEVICE_NUMBER_INFO) pIrp->AssociatedIrp.SystemBuffer;

if( pDeviceNumberInfo == NULL )

{

ntStatus = STATUS_UNSUCCESSFUL;

pIrp->IoStatus.Information = 0;

}

// Write

ConfigAddressData.u.nDataBit.UnUse0                = 0;

ConfigAddressData.u.nDataBit.UnUse1                = 0;


//64bit 까지만 PCI Common 한 부분이므로 0 ~ 16까지만 사용 가능. ( 4 * 16 = 64 )

ConfigAddressData.u.nDataBit.RegisterNumber       = 4; //[ 0x10 ]

ConfigAddressData.u.nDataBit.FunctionNumber      = pDeviceNumberInfo->nFunction;

ConfigAddressData.u.nDataBit.DeviceNumber         = pDeviceNumberInfo->nDevice;

ConfigAddressData.u.nDataBit.BusNumber             = pDeviceNumberInfo->nBus;

ConfigAddressData.u.nDataBit.Reserved                = 0;

ConfigAddressData.u.nDataBit.EnableBit                = 1;

WRITE_PORT_ULONG( (PULONG)ConfigAddress, ConfigAddressData.u.nData );

WRITE_PORT_ULONG( (PULONG)ConfigData, pDeviceNumberInfo->nMemory);


//Read

       ConfigAddressData.u.nDataBit.UnUse0                   = 0;

       ConfigAddressData.u.nDataBit.UnUse1                   = 0;

       ConfigAddressData.u.nDataBit.RegisterNumber        = 4; //[ 0x10 ]

       ConfigAddressData.u.nDataBit.FunctionNumber       = pDeviceNumberInfo->nFunction;

       ConfigAddressData.u.nDataBit.DeviceNumber         = pDeviceNumberInfo->nDevice;

       ConfigAddressData.u.nDataBit.BusNumber              = pDeviceNumberInfo->nBus;

       ConfigAddressData.u.nDataBit.Reserved                 = 0;

       ConfigAddressData.u.nDataBit.EnableBit                 = 1;


       WRITE_PORT_ULONG( (PULONG)ConfigAddress, ConfigAddressData.u.nData );

       nData = READ_PORT_ULONG( (PULONG)ConfigData );

       DbgPrint( "0x0CFC : 0x%08X \n", nData );