flashburn
flashburn

Reputation: 4528

BAR values from lspci -xxxx

I need to extract BAR values from the output of the lspci -xxxx. Here is my output:

00:0d.0 SATA controller: Intel Corporation 82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [AHCI mode] (rev 02)
00: 86 80 29 28 07 00 10 00 02 01 06 01 00 40 00 00
10: 41 d2 00 00 49 d2 00 00 51 d2 00 00 59 d2 00 00
20: 61 d2 00 00 00 60 80 f0 00 00 00 00 00 00 00 00
30: 00 00 00 00 70 00 00 00 00 00 00 00 0b 01 00 00
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 01 a8 03 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 40 00 3f 01 80 01 00 78 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 12 00 10 00 28 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

If I understand the PCI spec correctly my BAR values are located at addresses 0x10, 0x14, 0x18, 0x1C, 0x20 and 0x24.

However when I look at the output of lspci -vvvv

00:0d.0 SATA controller: Intel Corporation 82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [AHCI mode] (rev 02) (prog-if 01 [AHCI 1.0])
    Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
    Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
    Latency: 64
    Interrupt: pin A routed to IRQ 21
    Region 0: I/O ports at d240 [size=8]
    Region 1: I/O ports at 0000
    Region 2: I/O ports at d250 [size=8]
    Region 3: I/O ports at 0000
    Region 4: I/O ports at d260 [size=16]
    Region 5: Memory at f0806000 (32-bit, non-prefetchable) [size=8K]
    Capabilities: [70] Power Management version 3
        Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
        Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
    Capabilities: [a8] SATA HBA v1.0 BAR4 Offset=00000002
    Kernel driver in use: ahci

Region 5 is the one that matches the value shown in the output of lspci -xxxx. So for example the value at address 0x24 matches Region 5: Memory at f0806000. Why Region 0 through region 4 don't match? What is the meaning of I/O ports at d240 [size=8]

Upvotes: 1

Views: 10161

Answers (1)

Gil Hamilton
Gil Hamilton

Reputation: 12347

Regions 0, 2 and 4 actually do match. The low 2 bits of an I/O BAR are flag bits. And the lowest bit, in particular, is what specifies that these are I/O regions and not memory regions. See http://wiki.osdev.org/PCI#Base_Address_Registers.

I can't explain what's happening with regions 1 and 3. It looks to me like those should be displaying as:

Region 1: I/O ports at d248
Region 3: I/O ports at d258

Almost certainly each with size 8 as well, but that's actually determined dynamically -- by writing all 1's into the register and then reading back the result so no way to know for sure without trying that.

I suppose it's possible that the device is not correctly handling the case where all 1s are written to the registers, but that seems far-fetched (if that didn't work, how would an address already have been assigned to them).

So I dunno... possibly a bug in lspci?

The meaning of I/O ports at d240 [size=8] is that the device supports a region of length 8 in the "I/O space" (as opposed to memory space) and the region has been assigned the base address of 0xd240. For I/O space, you communicate with the device through these registers using "IN" and "OUT" instructions rather than ordinary memory load/store instructions.

Upvotes: 1

Related Questions