[我所知道的BIOS]->[PCI SCAN] 9

转自:http://biosengineer.blogspot.com/2007/10/bios-pci-scan-9.html
这次要提的是: PCI ! 

[About PCI device]
1. 每一个PCI device都有其 unique PFA(PCI Function Address). PFA由 bus number,device number & function number所组成.

Ex. USB device PFA is (0,6,0) <- USB is a PCI device and its bus/dev/function is 0/6/0


2. 有了PFA,就可以存取其 PCI configuration registers.

Ex. write USB PCI register 43h bit1 = 1
=>
mov eax, 80003040h
mov dx, 0cf8h
out dx, eax

mov dx, 0cffh
in al, dx
or al, 00000010b
out dx, al

* IO port 0cf8/0cfc 为 PCI config address port & data port,意即:将 address(80003040h)送到config port(0cf8h),然后从 data port(0cfch + 3)来存取 data(al)

* 注意: 32-bit address(80003040h) 中 bit[1:0] = 00b(固定的),所以虽然存取的是 43h,但还是写成40h ! 而要存取到 43h,则从 0cfch+3来达成 (因为: 0cfch<-> 40h,0cfdh<->41h,0cfeh<->42h, 0cffh<->43h) 

3. 基本的PCI device的 config registers可分成 2 parts:

A. header region(offset 00h~3Fh)
B. device specific region(40h~FFh)

在BIOS's PCI_SCAN stage中,会touch到 part A. Ex. command byte, BARs, Interrupt line, latency timer,...etc. 而Part B是制作 or design这个device的厂商所附加的 function/feature.

4. 每个PCI device都可以 request 之前所提的 4 resources:
A. memory resource:透过 Base Address Register(BAR)
B. IO resource:透过 Base Address Register(BAR)
C. Interrupt: 透过 interrupt pin
D. DMA: 这需要 device本身即具有 bus master function(status byte会indicate)


[Why need PCI SCAN]
现在的computer system泰半由许多PCI devices所组成,因此,BIOS POST中另一个重要的 task is : PCI_SCAN !!! 

它代表的是: BIOS会扫瞄 whole system,找出所有的PCI devices; initial them and build a linked list of PCI devices.在此list中的每一个node都代表一个PCI device,且含有其 characteristics ! 

Ex. Vendor ID,Device ID, PFA,Option ROM exist or NOT,...etc. 

一旦建好此表,以后的 tasks 随时都可以参考 !!! 

所以, after PCI_SCAN,有两件事完成了:
1. PCI device initialization;device config registers(Part A) are correctly set ...
2. One data structure is built to describe the PCI devices in whole system(建在memory中) 

这也是属于kernel code part ^_^ ( system 一般很少 hang at this stage...)


符合PCI spec的device即称为........PCI device ^_^

[补充] PCIe device

PCIe device => 符合PCIe spec的device(...废话...)

对软体而言,它仍是PCI device. 因此,基本的 header region and device specific region也有. 不过,PCIe新定义了 extended config space,即 offset 100h(含)以上,直到 FFFh( 所以, 最大可以至 4096 bytes )

存取 PCI config space的方式,用原来 0cf8/0cfc的方式依然可行,但只能 access offset 00h~FFh. 要 access 100h(含)以上的 extended config space,则必须用 memory transaction的方式 !

Ex. mov ax, [50400000h] <- read device (4,0,0)'s register 0;2 bytes

here 50000000h: PCIe extended base address. 可以从 chipset register得知
bit[27:20]: Bus information
[19:15]: Device information
[14:12]: Function information
[11: 8]: Extended Register 
[7:2]: DW number
[1:0]: Byte enable

因此,只要知道 PCIe extended base address,就可以像以前一样,可以任意存取 PCIe config registers, even > 0FFh !

除此之外, PCIe device可以由其 Capability pointer(points to a linked list of capabilities)辨认出来. 因为,在众多的 capabilities中,会有一个 PCIe capability;其 ID value = 10h.

Note: PCIe extended base address 要 reserve and report to OS. Size is 256MByte. 这是BIOS需要做的. (当然,BIOS也要将此 base address写入 chipset register,让 chipset 知道:有这样的 cycle时,是给PCIe device的 ! )

[补充] For P2P bridge

P2P bridge = PCI-to-PCI bridge. 其存在可以 introduce 另一 new PCI bus,可以容纳更多的 PCI device.

P2P bridge亦有其 PCI config space,但是 lauout 与 PCI device有点不同,大家可以参阅P2P spec并与PCI device's config space比较一下.

在 P2P config space中,我常遇到的 issue是和下列 register有关的:
- Primary bus register: offset 18h
- Secondary bus register: offset 19h
- Subordinate bus register: offset 1Ah

----------------------------------------
Notes:
这三个 registers是BIOS在 PCI_SCAN时会决定的;所代表的意义是:这个 P2P bridge的上面 PCI bus number is ? 下面的PCI bus number is ? 及包含此 P2P bridge的 "branch" 最深的 PCI bus number is ?

Ex. 18/19/1Ah of one P2P bridge is 0/2/3
=> 此 P2P bridge 是 "bridge" PCI bus 0 and 2的(桥接在 PCI bus 0 and 2之间);而包含此P2P bridge的 PCI branch(想像成 tree structure) 最大(深)的PCI bus number is 3
----------------------------------------


- memory base/limit
- IO base/limit

----------------------------------------
Notes:
这两个是 BIOS 在 PCI_SCAN时所 assign的. 所代表的是: resource "window" for devices behind this bridge.意即:若P2P bridge下面(就上例言:是 Bus 2上)有 PCI devices,则他们的 BARs 必须被包含在此 window 之内 !!!
---------------------------------------- 

[Practice] 
[Q]假设有一个 P2P bridge ,下面有一PCI device;现在必须要去 accessPCI device's Device ID/Vendor ID(that is, PCI config read). 但是,问题是:做这事的"点"要在 PCI_SCAN之"前"....那要如何做到呢 ^_^ ?


Ans:假如要在很早前(Ex. PCI SCAN之前)去 access P2P bridge后面的 device,照理是做不到的,因为: P2P bridge没有被正确的 configed...

在此例中,P2P bridge的 primary/secondary/subordinate bus要被 set,后面的device才能被 accessed到 !

所以,假如要在 PCI SCAN前就 access,则BIOS必须手动去 set 此 3 bytes;然后,PCI config access才能被 forward to 其后的 PCI devices...

[Q] 如何 disable memory or IO resource window ?
Ans: 只要将 base设成比 limit "大" 即可 !!!


---------------
- 相关讨论 Part1 -
---------------

前辈已经提到P2P Bridge我就直接问我的问题了

[Q1] Bridge 是用来扩充PCI Bus,在PCI Bus Spec与PCI-PCI Bridge Spec中定义,PCI Device是透过IDSEL来决定他的身分,其中PCI Bus Spec定义AD[31:11],而PCI Bridge Spec定义AD[31:16] 当做IDSEL,这中间差异为何? 为什么一个要从Bit 11开始当作是Dev 0 ,而另一个由Bit 16 才当作是 Dev 0 ?

Ans: 1. IDSEL对PCI device而言是 input,是用来当作 device's "chip-select"讯号. 而且,IDSEL "如何连接" 是 H/W决定的,BIOS无法决定. 

假如将板子上某个device's IDSEL "割断",则此 device将无法接受 PCI configuration read/write(以 ru.exe来说,就是按F6后,是看不到它的...)

那要如何决定 device's IDSEL ? 一般而言, board designer会将 "unused AD lines"拿来做 IDSEL,以连接至 PCI device.

在 configuration access时,所下的 Ex. "o cf8 80001020"(看起来是 I/O transaction)会被 host bridge转成 configuration transaction;此时, host bridge即可判断此 transaction 要 access的 device是否在该 PCI bus上;if YES 转成 Type 0 transaction;If NO 转成 Type 1 transaction,并往下发送...(host bridge只要 check latched "bus information"即可完成此判断 !)

以 Type 0言,AD bus上的 format as follows:
bit[1:0] = 00 ( indicates "Type 0" )
bit[7:2] indicates register number
bit[10:8] indicates function number 

那 Bus number ? Device number ?
=> Bus number不必知道 ! 因为:Type 0产生即代表 bus number = 现在的 bus #
=> Device number呢 ? 因为,此时(Config transaction && address phase) AD bus bit[31:11]没人用 !!! 因此, board designer会把此 21 bits拿来做 IDSEL用 !

因此, AD bus bit11 <-> device 0
12 <-> device 1
.......

当然,不可能 21 bits都拿来接 PCI devices;因为电路上的现实考量...

.................以上为:我所知为何从 bit11开始来当作 IDSEL................

以 Type 1言,PCI-PCI bridge收到后,会将其 bus information与自己的 secondary bus number比较;若是 addressed device是在 secondary bus上,则将 Type 1 -> Type 0;若否,继续包成Type 1往下一层送... 

在P2P spec v1.1 page 22 有一张表,说明 IDSEL generation(from primary address -> secondary address),其中有提到: if primary address bit[15:11] =0,则 secondary address AD [31:16] = 0000 0000 0000 0001;以此类推. 

所以,我觉得为什么 for P2P bridge 其 IDSEL可由 bit[31:16] 来决定的原因在此 !!!(表的关系...)

.................以上为:我推论为何从 bit16开始来当作 IDSEL................
[补充]
PCI config index register里面的资料其实和硬体解出configuration cycle是相关的. 
一.转换出来是type 0 cycle的话. 硬体只要做以下两件事.
1. mask 掉bus number(bit 16 ~ 31)以上的部份.
2.解码 device number的部份即可到对应的 AD bit. 所以其最低可以使用的就是AD11.也就是说一个bus上最多只能有 21个 devices(只是由于推动力问题, 往往是做不到的). 
Note:其实也可以设计成其他大于AD 11开始, 这要看chip设计者决定了.
二. 转换出来是type 1 cycle的话. 只要做
1. mask 掉reserved以上的部份(bit 24 ~31)
2. bit 0 = 1
由于P2P跟其他device不同的地方就是, 除了type 0 clcye以外, 还必须处理 type 1 cycle. 这也是分成两部份
一. type 1 -> type 0. 当 bus number 等于 secondary bus number 时候出现.
1. 解码 device number 到对应的 AD. spec中有提到转换的表. dev 0 = AD16....etc
2. 把 bit 0 由1 变成 0
二. type 1-> type 1. 当 bus number 介于 secondary bus number和 subordinate bus number
1. 直接往下一层送即可.交给其他的P2P 处理.

[Q2] 在IA32下,CONFIG_ADDRESS 会被转成Configuration Cycles,当Bus Number <>0 时,NB会转成Type 1 然后往 DMI送到SB,当P2P Bridge收到后,然后定址到Slot上面的PCI Device,这样说法对吗?

Ans: 总而言之, 是自己local bus上的,就会转成 Type 0,然后打在AD bus上,等待认领;若否就转成 Type 1,往下一个bridge送,继续寻找...对的人...for each bridge,都是一样...
[补充]
对 PCI spec是, 如果以Intel PCI express架构来说. 那个已经被封装成 pci express的 package了.没有所谓的 type 0, type 1 cycle了.


[Q3]PCI Device透过IDSEL来决定身分,那PCIE Device呢? 我查过资料,好像PCIE不需要IDSEL那他是如何决定Device Number ?

Ans: 我所遇的 PCIe device也是由 AD bit[31:11]中找线拉至 device's IDSEL决定的.不知其他家 chipset是如何 implement.
[补充]
PCI express 是internal routing. PCI express是个跟PCI 完全不同的架构. 只是为了软体相容性的关系, 把software架构做的跟PCI bus一样. PCI express是point-to-point架构, 一个link 只会连接一个device. 跟PCI 这种可以多个device在同一bus上是不一样的. 所以 device number对PCI express是完全不重要的.
Note. AMD的Hyper transport 也是基于一样的心态来设计软体架构的. 

※ PCIe 的device是 internal routing. 以规格来看,下一层的 device number都是为0. 

------------------
- 相关讨论 Part 2 -
------------------

DMI指的是 Intel 南北桥中间的通道 ! 之前也是不知P2P bridge部份关于IDSEL的配置,查了表才知道原来有这样的 mapping(primary address<->secondary address). 其实,可以说 "unused AD bus 会被拿来当 IDSEL用"就是了吧 ^_^
[补充]
是的, 只要软体能够知道routing 关系.怎么接都可以. 只要bus controller控好实际的IDSEL即可. P2P之所以会有严格规定(两项, 1. IDSEL&device number表, 2. secondary bus IRQ routing)是因为P2P 不一定是在板子上. 包含卡都可以有P2P bridge. 在板子上的P2P 可以靠BIOS来建立正确的 routing, 但是插卡不行. 所以必须把这些定义好. 这样 PnP software(BIOS or OS)才能正确的完成IRQ 分配.让卡正常工作. 所以如果观察某些板厂. 就算是真的p2p 没有存在在板子上, 很多PCI slot的IRQ routing都是依据p2p spec里面的规定做(因为SB的PCI bus还是落在P2P之后).


在 PCI scan时,BIOS会扫描整个系统的PCI architecture(包含 device & bridge);其扫描方式由BIOS's PCI kernel来决定 !
[补充]
其实了解PCI spec. 要写PCI scan其实可以效率好又正确. 常见的新进工程师写法大概就是 3个 loop来处理. bus:0~255, device:0~31, function:0~7. 扫个 256*32*8次, 反正都是程式做, 结果往往也看来正确.这种写法其实是不对的. (其实,若是多了解硬体的架构,就可以写出有效率的code了 ! 这也是F/W工程师的价值...)


Ex. Assume 系统架构是这样的: NB,P2Px3, PCIe bridge x2;其中:
A. 3 P2Ps的配置 is: P2P0下面接P2P1;P2P下面接P2P2
B. PCIe x 2 & P2P0都在 bus 0;其PFA为
NB(0,0,0)
P2P0(0,1,0)
PCIE0(0,4,0)
PCIE1(0,5,0)

=> 最后的 PCI achitecture is:

Bus 0----------------------
NB(0,0,0),P2P0(0,1,0),PCIE0(0,5,0),PCIE1(0,6,0)

*下面 Bus 1/2/3由 P2P0/1/2所 introduce:
Bus 1----------------------
P2P1(1,0,0)
Bus 2----------------------
P2P2(2,0,0)
Bus 3----------------------

*下面 Bus 4由 PCIE0所 introduce:
Bus 4----------------------

*下面 Bus 5由 PCIE1所 introduce:
Bus 5----------------------

所以,Bus number 是由BIOS's scanning "algorithm"所决定的;假如采用 depth-first,则会产生上述的结果 ! 决定后的值会填到 bridge的 Primary/secondary/subordinate bus number registers ! 

[Q]顺便问个问题好了. 其实function number不应该是永远需要scan的, 为什么?什么时候才需要scan function number?
Ans: 我想,对于 function number的问题,应该是: PCI header region offset 0Eh bit7代表: milti-function or NOT ! 因此,可以先 check此bit,再决定要不要往下扫了...这样又少做了许多虚工...^_^

Ex. PFA (0,3,0) 有回应(that is, Vendor ID/Device ID != 0xFFFFFFFF),则先check (0,3,0)'s PCI Reg0Eh bit7; if "1" then 此device为 multi-function device,还要再往下找 Ex. (0,3,1~7) 有无回应;if "0" then try next device number...!

[补充,加快速的的方式]
检查multi function bit是正确的, 但是不只是因为效率问题. 而是PCI 规格中, single function装置可以不解码 config cycle type 0 bit[8~10], 也就是说 一个 single function装置, 会对 所有的function number回应, 也就是会出现 8 个相同的device.

顺便说一下我的scan加速法. 其实我不是使用 vandor ID & device ID来判断装置存在与否. 我是用 class/subclass/interfae ID来作判断. default 只scan bus 0, 遇到 P2P bridge才会把taget bus number+1, 如果遇到multi host(host bridge 数量> 1)的板子才会完整扫描 255个 bus. ^_^



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

~转贴自艾克索夫实验室~
Rootkit in PCI Option ROM


「Rootkit」一字来自 UNIX 界;但目前通常用于描述 Windows 木马程式作者所运用的隐形技术。 
起初,Rootkit指的是一组程式,可让骇客躲过侦测。 为达成此目的,可执行的系统档案 (如 login、ps、ls、netstat 等) 或系统程式库 (libproc.a) 会遭到更换,或安装核心模组。 这两种动作只有一个相同目的;防止使用者收到正确资讯,知道电脑上发生了什么事。

首先介绍PCI的基本常识, PCI Bus是在约1990年由Intel发展出来, 用来连接主机板上的各项装置的汇流排标准, 后来成为业界的标准之一, Spec可以在PCI-SIG注册会员之后下载, 架构上简单的说, 就是一个Host bridge, 在一般的PC上通常指的就是North Brdige, 这个brdige后面就是bus#0(当然也有Multi Host-Bridge的状况, 这边举例的是最单纯的情况), 然后接到South Bridge, South Bridge之后可能接的是ISA Bus, IDE Controller, USB, IDE, DMA Controller等等, 如果bus#0上还有别的PCI Bridge, 这个Bridge后面就是bus#1, 如果有多个Bridge存在(PCI最多可以有256个bus), bus#就不一定是固定的了, 一个PCI Bus上可以有32个device, 每个device可以有8个function, 每个function都有属于自己的256个register. 在PCI的规范里, 256个register中的前0×40个是公定的功能, 从0×40到0xff则由各家厂商自行实作, 存取这些register的方法, 一般的PC上是透过IO port 0xCF8~0xCFF, 如果是新的PCI-Express则是直接透过Memory Mapped IO, 以存取记忆体的方式直接进行存取, 例如我们想要读取一个在bus#0 dev#1 func#0的register#40~43, 透过IO的方式如下:

mov eax, (0x01 << 31 ) // Type-1 PCI Configuration
+ (0x00 << 16 ) // Bus#0
+ (0x01 << 11 ) // Device#1
+ (0x00 << 8 ) // Function#0
+ 0x40 // Register#40
mov dx, 0xCF8 // Index Port 0xCF8 ~ 0xCFB
out dx, eax
mov dx, 0xCFC // Data Port 0xCFC ~ 0xCFF
in eax, dx // Get Data in EAX

如果是透过MMIO的方式则简单多了:

mov esi, (MMIO_BASE) + (0x00 << 20) + (0x01 << 15) + (0x00 << 12) + 0x40
mov eax, [esi]

今天我们比较有兴趣的是位在0×30~0×33的register, 在PCI Spec定义中, 这里的值存放的就是expansion rom在physical memory中被decode到IO的位址, 比如说这个位址是0xFE000000, 如果你在0×30把bit0设为0×1(io->mem decode), Command Register(0×04~0×05)的Memory Space Bit打开, 在0xFE000000的地方你就可以找到这个rom, 开头是0×55AA(这当然也是规范之一, 用来辨视是否为一个PCI rom), BIOS在POST过程中, 会逐一扫描位于主机板上所有的PCI Device, 假如device上有rom, 就会把它给拷贝到memory中, 然后用jmp指令跳到ROM开头offset 0×02(别忘了开头offset 0×00是0×55AA)的地方开始执行PCI ROM, 执行完后ROM会再把控制权交回到BIOS手上, 一般而言, 在传统记体空间中, 0xC0000~0xCFFFF是给VGA ROM用的, 0xD0000~0xEFFFF则是留给一般的PCI ROM使用, 当然各种情况下还是会有些许差异, 例如有些BIOS会保留0xE0000~0xFFFFF给自己使用, 像是BIOS的interrupt service, DMI data….等等杂七杂八的东西, 执行完的ROM仍然会保留在记忆体中, 因为有些ROM会修改IVT(Interrupt Vector Table), 将某些interrupt service导向自己的code, 像是VGA ROM可能就会hook int 0×10, 这是很合理的, 因为int 0×10是BIOS所提供用来控制萤幕的service, 聪明的你看到这里应该就知道前面所提的那篇文章想说什么了, 如果有个”恶意”的程式被埋在PCI ROM里面, 只要一开机就会自动被执行, 它的运作并不是一时的, 它可以hook某个OS一定会用到的BIOS Interrupt Service, 然后在这个interrupt service被呼叫的时候动作就可以了, 而且麻烦的是即使你format你的HDD也没用, 除非你把有问题的PCI Device从你的主机板上移除, 嗯….听起来蛮炫的, 但是, 有可能吗?

要回答这个问题之前, 需要知道一些基本的常识, 在保护模式下, 因为IO动作受到限制的关系, 要存取IO并不像在DOS那样容易, 但如果想尝试Re-flash一颗PCI ROM, 势必得进行IO动作, 所幸在Windows下这并不是不可能的事, 有些人可能知道利用SeTcbPrivilege和使用ProcessUserModeIOPL structure呼叫undocumented Native API NtSetInformationProcess()就可以达成目的. 一旦攻击者有办法修改PCI ROM, 他就可以利用文章中所提到的例子: int 0×10(Windows在开机过程中会透过Ke386CallBios()呼叫int x010), 作他想作的任何事了.

可惜不论哪种攻击方式, 最终都是要对OS kernel动手脚, 利用各种侦测工具(如: Archon Scanner), 一定可以找到有问题的地方, 如果最后的箭头指向PCI ROM, 我们可以透过上文所述, 将存在PCI Device和memory中的ROM给dump出来, 需要dump两边的rom, 是因为PCI Spec规范中允许实际上所需要配置的记忆体不一定要等于原本rom的大小, 借以节省保贵的记忆体(别忘了PCI ROM只能被配置到几个64KB的segment里而已), 然后向PCI Device的制造商索取正常版本的rom进行比对, 借以得知是否为被修改的版本. 假如发现有不一样的地方, 接下来可以朝几个方向继续分析是否为有问题的ROM, 我们可以检查一下它是否修改了不必要的IVT, 像PXE ROM就不太可能hook int 0×10, 或是有保护模式相关的程式码, 因为一般的ROM应该都是在real mode下执行, 所以应该不会切到protected mode, 如果有相关的程式码那就非常可疑, 还有rom里面是否有可疑的字串, 或是位在Windows Kernel位址空间里的32-bit address, 另外ROM里面也不太可能出现编码过的code, 如果rom里的code很难被disassemble, 或是充满了一堆obfuscated code, 那也是很有问题.

除了软体的方式, 最近兴起的新技术TPM也能克制这种攻击手法

8 意见:

poyuan 提到... 此文章已被作者删除。 八月 21, 2008 1:13 上午
poyuan 提到...

BIOS界的前辈您好, 无意间看到您的部落格, 对于您巨细弥遗的文章, 深为感动. 谢谢您在工作闲聊之余, 写了这些BIOS相关的文章. 
有一个问题想请教您: 敝公司做了一块PCI卡,发生了难以理解的现象, 就是在P915的主机板上可以WORK, 但是在P35 or P965的主机板上却不行?! 
用LA侧录PCI BUS的讯号后发现, BAR0被WRITE 0x80008000, 再被READ出
0x80008001, 最后BAR0被WRITE 
0xFFFF_FFFF, 等于BAR0是被关闭? 故无法map 到IO SPACE? 查了很久不知道原因, 可不可以请前辈给一点HINT?

八月 21, 2008 1:15 上午
Harrison Hsieh 提到...

我进入BIOS才两年,很多东西不懂! 大家互相讨论啦!

关于你的问题,我不太懂你测录的讯号,

不过我从PCI Spec 看到的步骤是:

1.对BAR写入"全部1"的值
2.读回BAR状态值并判断,假设bit 0=1 则代表这个PCI应该是实做IO Space

3.从bit 0开始往高位元检查第一个"1"的出现的权值..假设出现在bit 8 , 代表这是一个256 bytes的IO范围

4.填入IO BaseAddress (因为是256,所以填入的bit7:0无效)

所以解码范围是IOBASE~IOBASE+256

5.到CMD Register去Enable BAR

所以你看到写入FFFF_FFFF应该是我说的步骤1...所以你可能还是要继续测录一下后面的讯号,希望这些资讯能帮的上你的忙!

八月 25, 2008 8:58 上午
Colorben 提到...

个人问题请教:我要读取的rtl8139网卡都很顺利读到mac addr,在p35主板上内建好像是rtl8168也都从BAR就可以顺利读取,因为它们都是I/O mapping,但从ga-P965-ds3主版上内建网卡读取mac addr确读不到正确ㄉ值,因为它是memory mapping,从bar读到ㄉ值是f4000004,像这样我要如何正确读取网卡mac addr?

三月 17, 2009 8:19 上午
Colorben 提到...

我目前是在DOS下写ㄉ一个应用,由于必须得知网卡MAC ADDRESS,所以我写ㄌ这样ㄉROUTINE:
subGetMacAddr proc uses eax ecx dx si di
xor ebx,ebx
xor si, si ;index 0
mov ecx,020000h ;因为网卡ㄉclass=02h Subclass=00h
mov ax, 0B103h ;find PCI B/D/F
int 1ah
jc loc_err
mov di, 10h ;register 10h
mov ax, 0B10Ah ;read pcicfg dword
int 1ah
test ecx,1
jz Memoryio
mov dx, cx ;port
xor dl, dl
in eax, dx
out 0EDh, al
mov DWORD PTR MacAddr, eax
add dx, 4
in ax, dx
out 0EDh, al
mov WORD PTR MacAddr[4], ax 
loc_err: 
ret
Memoryio: 
我想在这里加入若网卡的BAR是memory mapping,就使用MMIOㄉ方式读取此时ㄉECX:0x0f4000004(marvell yukon 88E8056 配置BUS4 DEVICE0 FUNCTION0)
ret
subGetMacAddr endp

由于我只会碰到两块主机板:GA-965P-DS3及GA-P35-DS3L,GA-965P-DS3ㄉ主机板所配置ㄉ网卡是marvell yukon 88E8056 ㄉController(它是memory mapping),另外GA-P35-DS3L配置ㄉ网卡是RTL8168 Controller(它是IO映射),上面那ㄍROUTINE对RTL8168可以读取到MAC ADDRESS,而且外接RTL8139也可以读到MAC,会用上面ㄉ方法也是因为在网路上找到如附图ㄉ资料。但是marvell yukon 88E8056没办法读到MAC,红色区域就是想为它而写,不知是否能帮帮我。
我使用过以下方法但都读不到MAC ADDR
mov esi, (MMIO_BASE) + (0x04 << 20) + (0x00 << 15) + (0x00 << 12) + 0x10
mov eax, [esi]
当然我知道这和实作硬体有关,况且又没有SPEC,所以只能求救ㄌ。
TKS,Benson

四月 22, 2009 11:19 下午
Birdy 提到...

请问前辈, 最近公司要开发一个板子, 是有6个PCI slot. 3个slot后会接一个PCI-to-PCI bridge, 然后再扩3个slot出来.
但另外有一片PCI周边卡片, 上面是由一个PCI-to-PCI bridge去接4个PCI LAN.
请问当把这片周边接到第4-6的slot时, 上面的PCI LAN能动吗? 若第3个slot接了这片有PCI-to-PCI bridge的卡后, 第4-6的slot又接一片这个LAN卡, 这样子两片都能动吗?拜托帮我解答一下吧? 如果要能动, PCI SCAN与BUS的关系是怎样呢? 谢谢!

四月 28, 2009 10:54 上午
匿名 提到...

我现在在做的Project为AMD CPU+NB RS780+SB SB710.

挂在NB下有三个PCIE devices
两个Lan chip 和一个Mini PCIE slot

当我Clear CMOS 后的第一次开机
系统可是Scan 到两个LAN chip
但Scan不到Mini PCIE slot(Wireless lan)

第二次(CMOS 储存)开机时
则三个devices都抓不到(RU看不到)

有人可以帮忙嘛?
我目前用AMI core8

Grant
PS. email : [email protected]

二月 19, 2010 4:02 下午
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章