Article title: Linux-based PCI device driver design (2 ). Linux is a technology channel of the IT lab in China. Includes basic categories such as desktop applications, Linux system management, kernel research, embedded systems, and open source.
Chapter 2 Introduction to PCI bus
2.1 Linux support for PCI bus
Since PC's development, many bus standards have emerged: PCI, ISA, MCA, EISA, VLB, and Sbus are the bus standards available in the PC market today. Among them, PCI and ISA are the most common peripheral interfaces in the PC world. However, as ISA has been designed to be quite outdated, there is a trend that PCI will replace ISA in an all-round way, PCI bus has become the most common peripheral bus and the best supported bus in Linux kernel.
2.2 Overview of PCI bus
PCI is a set of complete specifications that define how different parts of a computer interact. The PCI specification covers the vast majority of aspects related to computer interfaces. This article mainly discusses how a PCI driver finds its hardware and obtains access to it.
PCI peripherals are determined by a bus number, a device number, and a function number.
PCI devices have three address spaces: memory space, I/O shared space, and configuration space. The first two address spaces are shared by all devices on the PCI bus, while the configuration space is private to the devices. Each PCI slot has a private enabling line for configuration transactions. the PCI controller can only access one peripheral at a time without address conflict. All these spaces are accessible to the CPU. During the initialization phase, the configuration information of peripherals is read from the configuration space by the initialization program in the Linux kernel. In this way, once the configuration register is read, the driver can access its hardware without passing the probe.
2.3 PCI configuration register
2.3.1 configure register layout
The layout of PCI configuration registers is standardized and consists of 256 bytes of address space. The first 64 bytes are standardized, and the rest are related to specific devices.
The following table shows the layout of the configuration space unrelated to the device.
Configure address offset register English name register Chinese name
00 H-01 H Vendor ID Manufacturer ID
02 H-03 H Device ID
04 H-05 H Command register
06 H-07 H Status register
08 H Revision ID Version Identification Number Register
09H-0bH Class Code Classification Code Register
0cH Cache Line Size CACHE row length register
0dH Latency Timer master device delay time register
0eH Header Type register
0fH bucket-in-teset Register contains self-test Register
10 H-13 H Base Address Register 0 Base Address Register 0
14 H-17 H Base Address Register 1 Base Address Register 1
18H-1bH Base Address Register 2 Base Address Register 2
1cH-19H Base Address Register 3 Base Address Register 3
20 H-23 H Base Address Register 4 Base Address Register 4
24 H-27 H Base Address Register 5 Base Address Register 5
28H-2bH carw.cis Pointer device bus CIS Pointer register
2cH-2dH Subsystem Vendor ID sub-device manufacturer ID
2eH-2fH Subsystem Device ID sub-Device ID
30 H-33 H Expasion ROM Base Address extended ROM Base Address
34H-3bH --- retain
3cH Interrupt Line disconnection register
3dH Interrupt Pin register
3eH Min_Gnt minimum authorization register
3fH Max_Lat maximum latency register
The discussion of all configuration items is clearly beyond the scope of this article. Generally, the technical documents released with the device will detail the registers it supports. We are only interested in the configuration items that help the driver find the device. they are: VendorID, DeviceID, and ClassCode. Each PCI peripheral puts its own values in these read-only registers, and the driver can use them to find the device.
The following header files, macros, and functions will be used by the PCI driver to find their hardware devices:
# Include
The driver needs to know whether the PCI function is available at the core. By including this header file, the driver obtains access to the CONFIG _ macro, including CONFIG_PCI.
CONFIG_PCI
If the core supports calling the pci bios, this macro is defined. Not every computer has a PCI bus. Therefore, core developers should make PCI support an option during compilation to save memory when running Linux on a computer without PCI. If CONFIG_PCI is not defined, all other functions in this list are unavailable. The driver should use pre-compiled condition statements to exclude all PCI statements.
# Include
This header file declares the following functions. This header file also defines the symbolic value of the error code returned by the function.
Int pcibios_present (void)
Since PCI-related functions are meaningless on computers without a PCI bus, the pcibios_present function is to tell the driver computer whether to support PCI. If yes, it returns a true Boolean value. Check pcibios_present before calling the functions described below to ensure that the computer supports PCI.
# Include
This header file defines the symbolic names of all numeric values used by the following function. Not all device IDs are listed in this file, but the content of this file has been increasing because the symbolic definitions of new devices are constantly added.
Int pcibios_find_device (unsigned short vendor,
Unsigned short id,
Unsigned short index,
Unsigned char * bus,
Unsigned char * function );
If CONFIG_PCI is defined and pcibios_present is true, this function is used to request information about the relevant device from the BIOS. The vendor/id pair is used to determine the device. Index is used to support several devices with the same vendor/id pairs. The call to this function returns the location of the device on the bus and the function pointer. If the return code is 0, the operation is successful. if the return code is not 0, the operation fails.
Int pcibios_find_class (unsigned int class_code,
Unsigned short index,
Unsigned char * bus,
Unsigned char * function );
This function is similar to the previous one, but it looks for devices of specific classes. If the return code is 0, the operation is successful. if the return code is not 0, the operation is incorrect.
Char * pcibios_strerror (int error)
This function is used to translate a PCI error code into a string.
2.3.2 access configuration register
After the driver detects the device, it can read or write the memory, I/O, and configuration space. In particular, access to the configuration space is extremely important to the driver because it is the only way to find that the device is mapped to somewhere in the memory and I/O space.
The driver or Linux kernel can use the following software interfaces to access the configuration space with 8-bit, 16-bit, and 32-bit data. These functions are all standardized, and the relevant prototype is Medium:
Int pcibios_read_config_byte (unsigned char bus,
Unsigned char function,
Unsigned char where,
Unsigned char * ptr );
Int pcibios_read_config_word (unsigned char bus,
Unsigned char function,
Unsigned char where,
Unsigned char * ptr );
Int pcibios_read_config_dword (unsigned char bus,
Unsigned char function,
Unsigned char where,
Unsigned char * ptr );
They read 1, 2, and 4 bytes from the configuration space of the device determined by the bus and function respectively. The where parameter is the byte offset from the beginning of the configuration space. The value retrieved from the configuration space is returned through ptr. If an error occurs, the return values of these functions are error codes.
Int pcibios_write_config_byte (unsigned char bus,
Unsigned char function,
Unsigned char where,
Unsigned char val );
Int pcibios _ write_config_word (unsigned char bus,
Unsigned char function,
Unsigned char where,
Unsigned char val );
Int pcibios _ write_config_dword (unsigned char bus,
Unsigned char function,
Unsigned char where,
Unsigned char val );
They write 1, 2, and 4 bytes to the configuration space respectively. The device is still determined by bus and function, and the value to be written is passed by val.
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