[Linux driver] using I/O commands to access the configuration space of a PCI Bus Device

Source: Internet
Author: User


Keywords
: PCI bus configuration space Operating System
Since the launch of PCI bus, it has been favored by many manufacturers with its unique characteristics and has become the mainstream of computer extended bus. At present, many technical personnel in China have the ability to develop PCI bus interface equipment. However, the Programming Technology of PCI bus, that is, the Operation Technology of PCI bus equipment, has always been a headache for technicians. The core technology of PCI bus programming is to understand and access the corresponding board configuration space. Generally, software programmers are unfamiliar with the principles of hardware devices, and it is difficult to understand and operate the configuration space. They hope hardware developers can directly tell them how to operate; although the hardware developers of the PCI bus have a profound understanding of its significance, it is difficult to operate the PCI board without much programming experience. Most of the results are hardware technicians who spend a lot of time and energy learning DDK, windrver and other driver development software.

During the development of PCI bus interface equipment, after in-depth research on the PCI bus protocol, from the perspective of the Protocol itself, the author found a convenient method for PCI configuration space operation, only simple I/o commands can be used to find a specific PCI bus device and perform read and write operations on all its configuration spaces. Once you read the content of the configuration space, you can obtain the system's resource allocation for the PCI bus device.

1. PCI bus configuration space and configuration Mechanism

To avoid resource occupation conflicts between PCI devices, the PCI bus uses the plug-and-play protocol. That is, when the system is established, the operating system allocates resources in a unified manner according to the requirements of each device. The Information allocated by the system is written into the configuration space registers of each PCI device and backed up within the operating system. Each PCI device has its own configuration space. The designer distinguishes the configuration space of different devices by driving the isdel pin of the backlog device (or slot. The first 64 bytes of the configuration space are called the pre-defined self-zone of the configuration space. Each device has the same definition and must be supported. The total space is called the device correlation zone, defined by the equipment manufacturer as needed. Configuration space information related to programming mainly includes:

(1) device ID and vendor ID. The configured space offset is 00 H, which is used to identify and find each PCI device. To ensure its uniqueness, the vendor ID should be obtained by applying to the PCI Special Interest Group (pCI sig.

(2) PCI base address (pCI base address), and the configured space offset is 10 ~ 24 h, the device sets a high value that can be read and written to indicate the size of the required resource space to the operating system. For example, if a device requires 64 KB of memory space, you can set the 16-bit high of a base address register in the configured space to read/write, and set the 16-bit low to 0 (only readable ). When the operating system is created, first write 1 to all bits. In fact, only the high 16 bits are received and set to 1, while the low 16 bits are still 0. in this way, when the Operating System reads this register, the returned value is ffff0000h. Based on this, the operating system can determine that the required space is 64 KB, allocate an idle memory space and fill in its address to the 16-bit high of the register.

For definitions and addresses of other configuration spaces that may be related to programming, see [1].

Because the PC-AT compatible system CPU only has two types of space: memory and I/O, no dedicated configuration space, the PCI Protocol requires the use of specific I/O space operations to drive the conversion of PCI bridges into configuration spaces. There are currently two conversion mechanisms: configuration mechanism 1 # And configuration Mechanism 2 #. Configuration Mechanism 2 # will not be used in the new design. The new design should use configuration mechanism 1 # To generate the physical operation of the configuration space. This mechanism uses two specific 32-bit I/O spaces, cf8h and cfch. These two spaces correspond to the two registers of the PCI bridge. When the Bridge Road sees that the CPU performs double-word operations on the two I/O spaces on the local bus, the I/O operation is changed to the configuration operation of the PCI bus. The register cf8h is used to generate the address (CONFIG-ADDRESS) of the configuration space, and the Register cfch is used to save the read/write data (CONFIG-DATA) of the configuration space ).

Configure the format of the spatial address register 1.

Cf8h (Local Bus ):

When the CPU sends a cfch operation on the I/O space, the PCI bridge checks the 31-bit configured space address register cf8h. If the value is 1, a corresponding configuration space read or write operation is generated on the PCI bus. The IP address is converted from the PCI bridge path to 2 based on the content of the configured space address register.

Cfch (Local Bus ):

The device number is decoded by the PCI bridge to generate a high IP address of the pci bus address, which is used by the designer as an idsel signal to distinguish the corresponding PCI device. The 6-bit Register number is used to address 62 dual configuration registers (256 bytes) in the null space of the PCI device ). The function number is used to differentiate the configuration space of a specific function of a multi-function device. The number of commonly used single-function devices is 000. The bus number of a certain PCI slot varies slightly with the system (main board). Most PCs are 1, and the industrial computer may be 2 or 3. In order to find a device, you should find it on each bus number of the system until it is located. If ~ If the device cannot be found on bus 5, the device does not exist.

After understanding the configuration mechanism in the above PCI protocol, you can directly operate on the I/O space of cf8h and cfch, search for a PCI device and access its configuration space, in this way, the operating system allocates resources for the PCI device.

2. Access the PCI bus configuration space with I/O commands

To access the configuration space of a PCI bus device, you must first find the device. The Basic Search is based on the fact that the configuration space of each PCI device contains a specific device ID and a vendor ID, which occupies the H address of the configuration space. The purpose is to obtain the bus number and device Number of the device. The basic process of searching is as follows: Use the I/O command to write the address register cf8h of the configuration space so that the highest bit is 1, the bus number and device are 0, and the function number and register number are 0, that is, to the I/O port cf8h80000000h; then read the data register cfch in the configuration space using the I/O command. If the value of this register does not match the device ID and the vendor ID of the PCI device, the device ID/bus number is increased sequentially. Repeat the preceding operation until the device is found. If you have checked all the device numbers/bus numbers (1 ~ 5) if the device still cannot be found, consider hardware issues. For a multi-function device, as long as the device configures the function number value corresponding to the register, the remaining steps are the same as for a Single-function device.

For example, to find a single-function PCI device with a device Number of 9054 H and a vendor number of 10b5, write the following program:

Code: Char bus; char device;

Unsigned int ioa0, IOD;

Int scan ()

{

Bus = 0; device = 0;

For (char I = 0; I <5; I ++ ){

For (char J = 0; j <32; j ++ ){

Bus = I; device = J;

Ioa0 = 0x80000000 + bus * 0x10000

+ (Device * 8) x 0x100;

_ Outpd (0xcf8, ioa0 );

IOD = _ inpd (0 xcfc );

If (iod0 = 0x905410b5) return 0;

}

}

Retrn-1

}

Call the subroutine scan (). If the returned value is-1, the PCI device is not found. If the return value is 0, the PCI device is found. The bus number and device Number of the device are in the global variables bus and device respectively. Using these two variables, you can easily access the configuration space of the device and obtain the allocated resource information. Assume that the PCI device occupies 4 Resource spaces, corresponding to the configuration space of 10 h ~ 1ch. The first two are the I/O space, and the last two are the memory space. If the base addresses are defined as ioaddr1, ioaddr2, memaddr1, and memaddr2, the corresponding program is as follows:

Code: Unsigned short ioaddr1, ioaddr2;

Unsigned int memaddr1, memaddr2;

Unsigned int iobase, IOA;

Void getbaseaddr (char bus, char device );

{

Iobase = 0x80000000 + bus * 0x10000 + (device * 8) * 0x100;

IOA = iobase + 0x10;/* Addressing base address register 0 */

_ Outpd (0xcf8, IOA );

Ioaddr1 = (unsigned short) _ inpd (0 xcfc) & 0 xfffc;

/* Shield low-and high-16-bit */

IOA = iobase + 0x14;/* Addressing base address register 1 */

_ Outpd (0xcf8, IOA );

Ioaddr2 = (unsigned short) _ inpd (0 xcfc) & 0 xfffc;

IOA = iobase + 0x18;/* Addressing base register 2 */

_ Outpd (0xcf8, IOA );

Memaddr1 = _ inpd (0 xcfc) & 0xfffffff0;

/* Shielded 4-bit low */

IOA = iobase + 0x1c;/* Addressing base address register 3 */

_ Outpd (0xcf8, IOA );

Memaddr2 = _ inpd (0 xcfc) & 0xfffffff0;

}

For the I/O base address, the minimum two D0 and D1 are fixed as 01. The address itself is invalid and should be blocked. For PC-AT compatible machine, I/O valid address is 16 bits, so high should also be blocked. For the memory address, the memory bit D0 is fixed to 0, while the D1 ~ D3 is used to indicate some physical characteristics of the address [1]. Therefore, its 4-bit low address should be blocked. It should be noted that the memory address is the physical address of the system. When Windows is running in protection mode, it must be converted to a linear address to directly read and write the memory space. Articles about this conversion method are common and will not be described here.

The above program provides a method to read the base address in the configuration space. A considerable number of PCI devices configure the working status of the device by configuring the device correlation area of the space. You can easily use the I/O command to set the operation status of the device without writing complicated drivers. This method has been applied in the development of PCI video image acquisition card.

Previous Article: implementation of a dynamic memory management module
Next article: [Linux Device Driver] device drivers (I)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.