Title: Device Discovery
1Device Discovery
- An introduction to the PCI configuration space
registers
2In the beginning
- The original IBM-PC was built using an assortment
of off-the-shelf components produced by a variety
of manufacturers - Certain peripheral components were a mandatory
part of the design (e.g., timer, keyboard,
diskette-drive, etc), while others were
considered optional add-ons (e.g., color
display, floating-point coprocessor,
line-printer, modem, mouse, etc)
3there was chaos!
- The PCs operating system was a mass-produced
piece of software (e.g. PC-DOS) that needed to
execute successfully on all the different PC
equipment configurations - There had to be a way for the OS to find out
which kinds of devices were actually attached to
the particular machine it was running on so it
could avoid attempts at using hardware which
wasnt present
4The ROM-BIOS POST
- During startup, the ROM-BIOS code did a Power-On
Self-Test routine to detect the presence of
those peripheral components that were standard
features of the PC, and also to initialize them
where necessary - For example, the Programmable Interrupt
Controller needed its mask-register to be
initialized, and the Programmable Interval
Timers latch-registers needed to be setup
5Simplified Block Diagram
CPU
main memory (amount varies)
optional FPU
optional EMS
system bus
keyboard controller
interrupt controller
programmable timer/counter
serial 1
serial 2
serial 3
serial 4
parallel 1
parallel 2
parallel 3
plus other peripheral components (not shown)
6Components were all different
- There was no standard way to detect the various
peripheral devices each needed its own
non-reusable code-sequence for discovering it
and configuring it to operate - System programmers had to learn details of the
unique designs for all the different possible
microprocessors capabilities
7Older probing methods
- Originally the IBM PC/ATs hardware and BIOS
supported up to 4 serial-port UARTs (Universal
Asynchronous Receiver/Transmitter) - IBMs PC designers reserved four I/O-port
address-ranges for these devices - COM1 0x03F8-0x03FF lt/dev/ttyS0gt
- COM2 0x02F8-0x02FF lt/dev/ttyS1gt
- COM3 0x03E8-0x03EF lt/dev/ttyS2gt
- COM4 0x02E8-0x02EF lt/dev/ttyS3gt
8checked reserved ports
- Example Any 16550 serial-UART device always has
a scratch register (at offset 7) a register
that performs no functions, but it can be used by
programmers to save, and read back, values - Thus system software can detect the presence of
these serial UARTs by attempting to write and
read back some test-values at these reserved
port-locations if those values can be read back
successfully, it means this UART is installed
9Probing for 16550 UARTs
ports .short 0x03F8, 0x02F8, 0x03E8,
0x02E8 ndevs .short 0 loop to count the
number of 16550 serial-port devices
installed xor esi, esi array-index
and loop-counter nxtry mov ports(, esi, 2),
dx base of port-address range add 7,
dx plus offset to scratch-register mov 0x55
, al setup test-value in AL mov al,
ah save copy of test-value in AH outb al,
dx try writing to the scratch
register in dx, al try reading back that
test-value xor ah, al see if these two
values agree jne fail the scratch-register
isnt there! incw ndevs else count this
16550 UART fail incl esi advance
array-index cmp 4, esi all reserved ranges
checked? jb nxtry no, try next expected
location when we arrive here, the ndevs
variable holds the number of UART devices found
10Some background on PCI
- ISA Industry Standard Architecture (1981)
- PCI Peripheral Component Interconnect
- An Intel-backed industry initiative (1992-9)
- Main goals
- Reduce the diversity inherent in legacy ISA
- Improve data-xfers to/from peripheral devices
- Eliminate (or reduce) platform dependencies
- Simplify adding/removing peripheral devices
- Lower total consumption of electrical power
11PCI Configuration Space
A non-volatile parameter-storage area for each
PCI device-function
PCI Configuration Space Header (16 doublewords
fixed format)
PCI Configuration Space Body (48 doublewords
variable format)
64 doublewords
12Example Header Type 0
16 doublewords
31
0
31
0
Dwords
Status Register
Command Register
Device ID
Vendor ID
1 - 0
BIST
Cache Line Size
Class Code Class/SubClass/ProgIF
Revision ID
Latency Timer
Header Type
3 - 2
Base Address 0
Base Address 1
5 - 4
Base Address 2
Base Address 3
7 - 6
Base Address 4
Base Address 5
9 - 8
Subsystem Device ID
Subsystem Vendor ID
CardBus CIS Pointer
11 - 10
reserved
capabilities pointer
Expansion ROM Base Address
13 - 12
Minimum Grant
Interrupt Pin
reserved
Interrupt Line
Maximum Latency
15 - 14
13The Header Type field
7 6
0
Header Type
Multi- Function Device flag
Configuration Header Format ID
0 Single-Function Device 1 Multi-Function
Device
14Interface to PCI Configuration Space
PCI Configuration Space Address Port (32-bits)
31 23
16 15 11 10 8 7
2 0
reserved
E N
bus (8-bits)
device (5-bits)
doubleword (6-bits)
function (3-bits)
00
CONFADD ( 0x0CF8)
Enable Configuration Space Mapping (1yes, 0no)
PCI Configuration Space Data Port (32-bits)
31
0
CONFDAT ( 0x0CFC)
15Reading PCI Configuration Data
- Step one Output the desired longwords address
(bus, device, function, and dword) with bit 31
set to 1 (to enable access) to the
Configuration-Space Address-Port - Step two Read the designated data from the
Configuration-Space Data-Port
read the PCI Header-Type field (byte 2 of dword
3) for bus0, device0, function0 movl 0x800000
0C, eax setup address in EAX movw 0x0CF8,
dx setup port-number in DX outl eax,
dx output address to port mov 0x0CFC,
dx setup port-number in DX inl dx, eax
input configuration longword shr 16, eax
shift word 2 into AL register movb al,
header_type store Header Type in variable
16Examples of VENDOR-IDs
- 0x8086 Intel Corporation
- 0x1022 Advanced Micro Devices, Inc
- 0x1002 Advanced Technologies, Inc
- 0x10EC RealTek, Incorporated
- 0x10DE Nvidia Corporation
- 0x10B7 3Com Corporation
- 0x101C Western Digital, Inc
- 0x1014 IBM Corporation
- 0x0E11 Compaq Corporation
- 0x1057 Motorola Corporation
- 0x106B Apple Computers, Inc
- 0x5333 Silicon Integrated Systems, Inc
17Examples of DEVICE-IDs
- 0x5347 ATI RAGE128 SG
- 0x4C58 ATI RADEON LX
- 0x5950 ATI RS480
- 0x436E ATI IXP300 SATA
- 0x438C ATI IXP600 IDE
- See this Linux header-file for lots more
- lt/usr/src/linux/include/linux/pci_ids.hgt
18Defined PCI Class Codes
- 0x00 Legacy Device (i.e., built before
class-codes were defined) - 0x01 Mass Storage controller
- 0x02 Network controller
- 0x03 Display controller
- 0x04 Multimedia device
- 0x05 Memory Controller
- 0x06 Bridge device
- 0x07 Simple Communications controller
- 0x08 Base System peripherals
- 0x09 Input device
- 0x0A Docking stations
- 0x0B Processors
- 0x0C Serial Bus controllers
- 0x0D Wireless controllers
- 0x0E Intelligent I/O controllers
- 0x0F Encryption/Decryption controllers
- 0x10 Satellite Communications controllers
- 0x11 Data Acquisition and Signal Processing
controllers
19Example of Sub-Class Codes
- Class Code 0x01 Mass Storage controller
- 0x00 SCSI controller
- 0x01 IDE controller
- 0x02 Floppy Disk controller
- 0x03 IPI controller
- 0x04 RAID controller
- 0x80 Other Mass Storage controller
20Example of Sub-Class Codes
- Class Code 0x02 Network controller
- 0x00 Ethernet controller
- 0x01 Token Ring controller
- 0x02 FDDI controller
- 0x03 ATM controller
- 0x04 ISDN controller
- 0x80 Other Network controller
21Using the BIOS PCI services
- To assist system software authors in doing
device detection, the PCs ROM-BIOS now
includes service-functions that search for
particular devices or classes of devices - These service-functions are invoked while in
real-mode via software interrupt 0x1A, with
function-number 0xB1 in register AH and with a
PCI sub-function ID-number in register AL (about
a dozen sub-functions)
22PCI BIOS example
- Search for your PCs ethernet controller (Device
Class is 0x02, Sub-Class is 0x00)
code-example Finding the Vendor-ID for your
computers ethernet controller mov 0xB103,
ax PCI Find Class function mov 0x020000,
ecx PCI Class (network/ethernet) xor esi,
esi initialize search index int 0x1A
request BIOS service jnc found function was
successful jmp error else the function
failed found if successful, BX
bus/device/function mov 0xB109, ax PCI Read
Configuration Word mov 0x0000, di PCI
Register-Number int 0x1A request BIOS
service jc success vendor-ID is in register
CX jmp error else the function failed
NOTE This code was written for execution while
the Pentium is in real-mode
23Some references
- Professor Ralf Browns Interrupt List (see the
online link on our CS630 website) - Tom Shanley and Don Anderson,
- PCI System Architecture (4th Edition),
- MindShare, Inc. (Addison-Wesley, 1999)
24Demo Program
- We created a short Linux utility that searches
for a systems PCI devices (named pciprobe.cpp
on CS630 website) - It uses some C macros that expand to Intel
input/output instructions -- which normally are
privileged instructions that a Linux
application-program is not allowed to execute
(segfault!) - Our system administrator (Alex Fedosov) has
created a utility (named iopl3) that will allow
your command-shell to acquire root privileges
25In-Class Exercise
- After you have experimented with running the
pciprobe.cpp utility (be sure you run the
iopl3 program first), see if you can modify
pciprobe so that it will display the Class Code
for each PCI device-function that it identifies
as being present - This will give you practice in reading some
useful data from PCI Configuration Space