`
film
  • 浏览: 224809 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

关于硬件设备的PCI总线 位置 功能的说明

 
阅读更多
关于硬件设备的PCI总线 位置 功能的说明。
2009年02月04日 星期三 下午 11:28

一直没弄明白“功能”这个参数代表啥,总算明白了。见下。好文章要存下来。。

Bus Number
Device Number
Function Number
Register Number

There are up to 256 available Buses on a PCI system, most commonly all the cards and chips will be located on Bus 0 and Bus 1.
When scanning for hardware, it's a good idea to scan all 256 buses as it won't take that much additional time.

A Device is a physical thing on the PCI bus. It could be a video card, an ethernet card, a Northbridge, anything. There is a software maximum of 32 devices that can exist on each bus. The physical hardware limit is much lower than this due to electrical loading issues, but we won't get into that.
Devices on a motherboard are typically scattered throughout the 32 devices, holes can and will exist. Your software must scan all 32 devices on each bus.

All devices have at least 1 function. Multi-function devices, such as a combination modem/soundcard will usually have 2 devices, typically numbered 0 and 1. There are 8 possible functions per device, numbered 0-7. Any device that has more than 1 function is (hey clever!) called a multi-function device. Functions start numbering at 0 and work up to 7.

Every function of a device has 256 eight-bit registers. Registers 0-3F are defined by the PCI specification and provide a wealth of information about the particular function. Registers 40-FF are vendor defined and control the properties of the function itself. Without vendor specific documentation, these registers should probably be left untouched.

A typical PCI function looks like this:

x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF
00000000: B7 10 55 90 17 01 10 02 30 00 00 02 08 50 00 00
00000010: 81 10 00 00 00 00 00 0C 00 00 00 00 00 00 00 00
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 B7 10 55 90
00000030: 00 00 00 00 DC 00 00 00 00 00 00 00 0B 01 0A 0A
00000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000050: 00 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00
00000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000000A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000000B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000000C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000000D0: 00 00 00 00 00 00 00 00 00 00 00 00 01 00 01 F6
000000E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000000F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Registers 0 and 1 are defined by the PCI spec as being the vendor ID. The vendor ID is a 16bit value, in this case 10B7h
Register 2 and 3 are the device ID, 9055h in this example.

By looking up the vendor ID number 10b7 in the PCI vendor database you can see this is a 3COM card. The 9055h is a 3COM generated number which describes what model card this is.

Other registers can tell us it's an Ethernet controller, it's using IRQ 11, uses a base I/O address of 1080h and more. Refer to a pci specification to get all the details, as those are outside the scope of this document.

So, how do you get to all these registers in PCI space?


Accessing these registers is sorta like accessing CMOS memory in that you first send an index value (a pointer to the register you want to access) to the index port, then you read or write the data to/from the data port. The index is going to be a combination of all 4 above mentioned components, (bus, device, function, register)

In the x86 world, the index port always located at 0CF8h and the data port is always located at 0CFCh in I/O space. Most system BIOSes have software interfaces to abstract the index/data port access from you. I describe both methods below. Refer to Ralph Brown's interrupt list for details on the BIOS method of reading/writing PCI

Before you can get to any PCI function's registers, you should probably make sure the PCI interface exists first!

Detecting the PCI bus

you can detect the PCI bus a couple different ways. the easist one is to call the PCI BIOS interface directly and do an installation check.
note that you can also do a non-80386+ check by issuing this call and only check DX for "CP" (4350h), but when have you ever seen a 286 with a PCI bus?

.386
mov ax, 0b101h ; interrupt 1a function b101
int 1ah ; will tell us if there is a PCI
cmp edx," ICP" ; bus on the board.
jz yup ; EDX=20494350h
; nope
yup:

------------------------------------

You can also find the PCI bus using I/O by just doing a quick read to port CFCh.

mov dx, 0cfch   ; config data port
in eax, dx
cmp eax, -1 ; FFFFFFFF?
jz nope ; something must exist in PCI land
; yup
nope:

you will simply receive the data from the last PCI operation that was completed. This is by no means a foolproof method, but can do the job for quick-n-dirty type applications.

finding a device on the PCI bus:

there are 2 ways of finding a PCI device on the bus. You can either use the PCI BIOS interface call, or direct hardware I/O.
Here's the BIOS way:

INTEL_VENDOR_ID EQU 8086h   ; intel's unique sig #
INTEL_EXP_NIC EQU 1227h ; sample PCI device etherexpress 10/100 NIC
.386
mov ax, 0
b102h ; interrupt 1a function b102
mov dx, INTEL_VENDOR_ID
mov cx, INTEL_EXP_NIC
xor si, si ; 0=1st device, 1=2nd etc.
int 1ah
jc nope


; once returned from this call, BH=bus number, BL=device/function #
nope:

----------------------------------------------------------------
in the above example, SI will normally be zero, unless you are trying to locate the 2nd or more instance of the same PCI device.
(ie, you had 3 PCI intel etherexpress cards installed)

an extremely handy utility for snooping through the PCI bus on your system is a DOS program called PCIVIEW.EXE. i was able to locate this utility on the net by simply searching for pciview.exe

--------------------------------------------------------------------------------------
the non-BIOS way:
locating a specific device on the PCI bus requires you to understand how the PCI configuration cycle is broken down.
it's a 32bit value that looks like this:

bit 31=1 (bit is always set for a PCI access)
bits30:24=0 (reserved)
bit 23:16=bus number (0-255)
bits15:11=device # (0-31)
bits10:8=function # (0-7)
bits7:0=register number (0-255)

you send the above bit-encoded value out to the index port (cf8h) and then do a 32bit read from the data port (cfch)
here's how to read the vendor and device ID from a device sitting at bus 0, device 7, function 3.

BUS             EQU     0
DEV EQU 7
FN EQU 3
VEN_ID EQU 0 ; vendor ID=PCI regs 0,1
PCI_INDEX EQU 0CF8h
PCI_DATA EQU 0CFCh
.386
mov ax, 8000h ; set bit 31 (after shift)
or al, BUS ; add in bus number
shl eax, 16
mov     ax, DEV
shl ax, 11 ; slide device # up to bits 15:11
mov al, FN
or ah, al ; add function into bits 10:8
mov al, VEN_ID
cli
mov dx, PCI_INDEX
out dx, eax ; send our request out
mov     dx, PCI_DATA            
in eax, dx ; read back 32bit value.
sti

Remember that PCI registers are 8 bit values. The above read from PCI_DATA reads a 32bit value, or 4 PCI registers. In the above example, after the read, EAX = device ID, AX = vendor ID.
Per the PCI specification, the vendor ID is always registers 0 and 1, and the device ID is registers 2 and 3.
Thus, AL=register 0, AH=register 1, EAL=register 2, EAH=register 3.

PCIe update:

PCI express did some minor tweaks to the interface. Specifically, they changed the number of config registers from 255 to 4096. The 1st 255 registers still look and feel just like regular PCI registers-in fact, they are also readable and writable using the same methods described above.

The additional registers however, are only available through a memory mapped subsystem, and it's a total pain in the cheeks to get to them.

For PCIe, it turns out that the *ENTIRE* PCI subsystem has been mapped into a 256MB chunk of system memory. On the 2 machines that I had a chance to play with, this memory map started at phsyical address 0xe0000000. That's way up near the top of 4Gig of memory. I suggest you grab a memory browser/editor that allows you to poke around in memory out there and explore the area for yourself.

At 0xe0000000, you'll see a copy of every PCI(e) register from Bus 0, Device 0, Function 0.
Function 1 follows at 0xe0000100, Function 2 at 0xe0000200, etc, all the way up to Bus 255, Device 31, Function 7. (ok, this is guess. I'm not sure if each function is packed into memory as tightly as every 0x100 bytes-my machines didn't have multi-function PCI devices, but you can clearly see that all PCI registers are there in memory.)

Any time there was no PCI device, such as BUS 89, Device 9, Function 3, the memory just returns all FF's because nothing is there to respond to the read. To me, it seems like a HUGE waste of memory space, considering that there is already a perfectly good mechanism for accessing PCI, and all they'd need to do is use a couple of the reserved bits in the 32bit index port to allow access to all the extended PCIe registers, but I digress...


Changing any register value here in memory is just like changing them via I/O ports the old way; the memory map is just a mirror of whatever you see through the index and data ports and vice versa.

On your machine, your PCIe memory map might not be at 0xe0000000. How did I find this magic value? This is where the pain in the cheeks starts, with ACPI.

Tucked away in the ACPI Root System Description Table (RSDT) is an entry for the PCI Express memory mapped configuration space base address Description Table, or MCFG for short.

In order to get there, you have to parse the ACPI tables. Here's how to do it:

1) search in memory (real mode) in the BIOS segments 0xE000 or 0xF000 for the byte sequence:
"RSD PTR "
2) add 0x10 to the address that "RSD PTR " is found, to get a 32bit pointer to where the main ACPI RSDT tables are located.
3) You will need to be in protected mode, or unreal mode to access memory to do this next part.
Starting at the 32bit address of the RSDT tables (should be in high memory, my NVidia board put them at 0x7FEF3040) search for the keyword "MCFG" or parse through all the tables until you get to one labeled "MCFG". At offset 0x2c from "MCFG" will be another 32bit pointer to the PCIe memory map.

My Nvidia board's "MCFG" table looks like this:

4D434647 3C000000 012C4E76 69646961     MCFG<....,Nvidia    
4E564441 41435049 312E3042 4E564441 NVDAACPI1.0BNVDA
00000000 00000000 00000000 000000E0 ...............á
00000000 000000FF 00000000 00000000 .......ÿ........

I've got an ACPI dump program (for DOS) here: http://www.waste.org/~winkles/acpidump although it is out of date and won't dump out the MCFG table, it'll at least point you in the right direction of where to look.


It appeared to me that very few PCIe devices have any additional registers above the 255 that are available through the index and data ports, so getting to them this way appears to a bit of moot point, but I'm sure eventually something will come up, so now you know.


feel free to contact me with questions or comments.

版权声明:本文为博主原创文章,未经博主允许不得转载。

分享到:
评论

相关推荐

    PCI主模式设备开发套件PDC4000介绍(93C56)--开发PCI板卡软硬件的模板

    一、 硬件说明 特点: 1,支持PCI2.2规范。 2,直接支持Block DMA(块传输),Scatter/Gather List DMA。 3,支持中断,DMA中断,硬件中断等等。 4,局部总线时钟自由设定。 5,局部总线配置自由设定,支持8位...

    计算机组成原理本科复习题2.rar

    5.(11分)画出PCI总线结构框图,说明HOST总线、PCI总线、LAGACY总线的功能。 6.(11分)若设备的优先级依次为CD-ROM、扫描仪、硬盘、磁带机、打印机,请用标 准接口SCSI进行配置,画出配置图。

    声卡常见故障分析

    一般是因为PCI显卡采用BusMaster技术造成挂在PCI总线上的硬盘读写、鼠标移动等操作时放大了背景噪声的缘故。解决方法:关掉PCI显卡的BusMaster功能,换成AGP显卡,将PCI声卡换插槽上。 常见故障六:无法正常录音 ...

    Visual Basic 数据采集与串口通信测控应用实战(part1)

    作者: 李江全 汤智辉 朱东芹 ...7.5.2 pc与can总线模块构成的dcs程序设计用软、硬件 295 7.5.3 pc与can总线模块构成的dcs程序硬件线路图 295 7.5.4 设计任务 296 7.5.5 任务实现 296 参考文献 302

    Visual Basic 数据采集与串口通信测控应用实战(part2)

    作者: 李江全 汤智辉 朱东芹 ...7.5.2 pc与can总线模块构成的dcs程序设计用软、硬件 295 7.5.3 pc与can总线模块构成的dcs程序硬件线路图 295 7.5.4 设计任务 296 7.5.5 任务实现 296 参考文献 302

    龙芯3A处理器用户手册

    10.1 PCI/PCI-X控制器 63 10.2 LPC控制器 63 10.3 UART控制器 63 10.3.1 数据寄存器(DAT) 63 10.3.2 中断使能寄存器(IER) 63 10.3.3 中断标识寄存器(IIR) 63 10.3.4 FIFO控制寄存器(FCR) 63 10.3.5 线路控制...

    BIOS中英文对照表

    说明 每个主板都不一样 Time/System Time 时间/系统时间 Date/System Date 日期/系统日期 Level 2 Cache 二级缓存 System Memory 系统内存 Video Controller 视频控制器 Panel Type 液晶屏型号 Audio ...

    Dell服务器BIOS设置完整版.docx

    PCI IRQ Assignment(PCI IRQ 分配) 显示一个用于更改 IRQ(已分配给 PCI 总线上的各个集成设备以及所有需要 IRQ 的已安装扩充卡)的屏幕。 Serial Communication(串行通信)(默认设置为Off[关]) 请参阅。 ...

    计算机组成原理 练习题与答案 本科

    5. PCI总线采用A______协议和B______仲裁策略,具有C______能力。 三、(10分)已知X=2010×0.11011011,Y=2100×(-0.10101100),求X+Y。 四、(9分)某加法器进位链小组信号为C4C3C2C1,低位来的进位信号为C0,...

    北语20春《计算机基础》作业4满分答案.docx

    A 可安装多个服务器 B 可共享打印机 C 可共享服务器硬盘 D 所有的数据都存放在服务器中 答案:D 15 微型计算机硬件系统中最核心的部件是() A 主板 B CPU C 内储存器 D I/O设备a 答案:B 16 在计算机中,图像显示...

    北语20春《计算机基础》作业4.txt

    在一条计算机指令中规定其执行功能的部分称为() A.址码 B.操作码 C.目标地址码 D.数据码 答案:B 8.Excel工作表的单元格出现"#######"时说明( )。 A.数据输入太长 B.数据计算出错 C.数据宽度不够 D.地址引用不正确 ...

    uboott移植实验手册及技术文档

    实验三 移植U-Boot-1.3.1 实验 【实验目的】 了解 U-Boot-1.3.1 的代码结构,掌握其移植方法。 【实验环境】 1、Ubuntu 7.0.4发行版 2、u-boot-1.3.1 3、FS2410平台 4、交叉编译器 arm-softfloat-linux-gnu-...

    香槟网络系统 G H O S T XP SP3 7.0

    1.综合驱动包以全面为主导,收集了大量目前流行的硬件设备驱动。 2.适用于WinXP_32Bit平台,部份驱动去除了对Win2000以及64Bit平台的支持。 3.包含硬件智能判断驱动选择程序及相关组件,可在桌面环境下全静默安装已...

Global site tag (gtag.js) - Google Analytics