PCItree displays all components of the PCIbus as a tree structure. The Config Space of devices can be  read and edited. If a device features io or memory space it can be read and edited as well (but be carefull! it can hang or even damage your hardware!).


Installation:

    make sure that the following files are in the same directory as pcitree.exe:     Win NT/2000 : hlp.sys must be copied to \WINNT\SYSTEM32\DRIVERS directory.
    Windows XP / Vista / 7: hlp.sys must be copied to \WINDOWS\SYSTEM32\DRIVERS directory.

    Important: You need administrator rights to install and to run PCItree.
           If you use Windows Vista or Windows 7 you have to switch off the UAC



User Guide:


tree list:

pcitree scans the PCIbus of the host PC and displays the found components as a tree. components are found if a read of DID and VID doesn't return 0xffffffff.

last PCI bus number: The value of the highes PCIbus number is displayed right above the tree pane

b.d.f : Each PCI component has an integer number for bus, device and function.

direct select: in case you think not all components in the PCIbus system are found:
any b.d.f can be choosen directly by the three spin controls in the direct select box. A config read is done for this b.d.f and the result is displayed in the Config Space Dump.
 
If for a choosen b.d.f a PCI component exists it is highlightet in the tree pane.

++ expands all levels of the tree
-- collapses all levels of the tree
refresh tree rescans the whole PCIbus
save tree writes the tree structure to a file
reset bridge resets the secondary PCIbus of a PPB. After the reset the config space of all devices behind the bridge is restored.








back to top

Config Space Dump:

use BIOS int checkbox:
type 1 access uses IO ports to write/read the config space (default)
type 0 access uses BIOS INT 13 calls

Nr of ConfRegs:
16 : config space from adress 0 to 0x3f is read (default)
64 : config space from adress 0 to 0xff is read

refresh dump: rereads the config space of the device and displays it

If a component is selected in the tree the register contents of its configuration space (16 or 64 dwords) are displayed in the lower right window.

If a BAR is used (value != 0) it is indicated wether its memory or io space.
You can double click on a BAR to view/edit the memory/io space
You should know what happens if you read memory/io space !!

The following information is extracted and decoded from the config space:
 VendorID:   value & decoded
 DeviceID:   value
 Subsys VID:   value & decoded
 Subsys ID :   value
 Base/Sub Class code:  value & decoded
 Interrupt Pin/Line:  decoded
 revision number:  value

you can click and double click on a Config Space Register in the list box

back to top

 

edit ConfReg:

you should not edit a Configuration register ! unless you know what you do.

if you click on a Config register in the list box its DWORD contents is displayed
in the edit box. You can modify this value (the 1st character must be an x). The
string will be scanned by sscanf(str, "x%X", &data).

Write ConfReg writes the DWORD value of the edit box to the Config register.
  The sscaned value is displayed below the edit box (for feedback).

refr after wr. refreshes the dump after the Write Confreg

back to top

 

show INT routing: see

this button opens a window with a map of the PCI interrupt routing. The routing
information is taken from the config spaces of all PCI components (byte registers
with adress x3C and x3D).
If a PCI component has a INT pin it is routed to one of the 15 INT lines of the
host. Shared interrupts are possible.

A component with a INT pin is displayed as "X(b.d.f)DDDD.VVVV" where X is one of
the INT pins INTA to INTD. b.d.f is bus.device.function number. DDDD is DeviceID
 and VVVV is VendorID.

back to top

show Mem Map:

this button opens a window with a map of the devices' io/memory spaces. The address
information is taken from the BARs of the config spaces of all PCI components.
The first column displays the PCI address. If a BAR falls into the this address
range it is listed in the next columns. A device entry has the format
"BARx(b.d.f)DDDD.VVVV" where x is a number one of device's BAR. b.d.f is
bus.device.function number. DDDD is DeviceID and VVVV is VendorID.

Note: the range of the BAR space is not derieved because it needs a READ-WRITE-READ-
WRITE sequence to the BAR which can cause malfunctions of the PCI system !!
(see "BAR space" below)

back to top

 

Reset PCI bridge:

you can do a reset on the secondary PCIbus of a PCI to PCI bridge.
After the reset is performed the configuration registers of the devices behind the bridge are restored with their old values.
During the reset process NO device driver should access the involved devices because the BARs become temporarily 0.

back to top

 
 

BAR space:

 You can double click on a BAR in the Config Space list to view/edit the
  memory/io space
  You should know what happens if you read memory/io space !!

 Only 32 bit adress space is supported.

BAR space detection:
If you click YES in the message box the following happens:
  the BAR in the ConfigSpace is read and stored
  the BAR is written with 0xffffffff (!!)
  the BAR is read. With the read value the size of the memory/io space is determined
  the BAR is written with the stored BAR value
  a linear adress of 1Kbyte is mapped to the physical adress (the contents of the BAR)
  a new Dialog window with a list box is opened
   (In some cases the described BAR detection can cause malfunctions of the PCI system because the BAR is temporarily changed !!)
If you click NO then the described procedure is not done. Instead a size of 1 MByte is assumed.

back to top

BAR space Dialog window: 

auto read memory:
  the content of the display range is not read when the Dialog window is opened.
  If you select an address in the list box the dword of the address is read.
  If you want to read the range of the memory check the button auto read memory and push refresh view.

Display range:
  128 Bytes:  only the first 128 Bytes of the selected 1Kbyte range are displayed
   and refreshed (faster cont. cycles & shorter cycles to
   view with a logic analyzer)
 1024 Bytes:  the whole 1K range is displayed in the list box (default)

If the size of the memory/io space is smaller only this space is displayed.

select view range:
  If the size of the memory/io space is bigger than 1Kbyte then you can select another
  1Kbyte block to be displayed in the list box. Just move the scrollbars for KB range
  and MB range.
 

list box contents:
 1st col: DWORD contents (MSbyte:LSbyte)
 2nd col: address offset in the memory/io space
 3rd col: ASCII character of the 4 bytes (LSbyte:MSbyte)
 

refr. view  : rereads the selected 1Kbyte (or 128 Byte) block and displays it in the  list box

back to top

edit memory:

select one DWORD in the list box or select a range of DWORDs in the list box

the first DWORD of the selected range is displayed in the edit box. Physical address and number of selected DWORDs are displayed at the right of the edit box.

You can modify the value in the edit box (the 1st character must be an x). The string will be scanned by sscanf(str, "x%X", &data) when the write button is pushed. The sscaned value is displayed below the edit box (for feedback).

Write Memory writes the DWORD value of the edit box to the selected range with the following options:
 loop on/off. continously loops accesing the selected range
  stops if button is being unchecked
 toggle.  toggles (inverts) every second DWORD to be written
 count.  increments each WORD of the DWORD for the next write access
 verify. after the selected range is written it is read and compared to the
  written values. If an error occurs (the cont. loop is stoped and) the
  false values are highlighted in the list box
 refresh view after write.  refreshes the whole list box after the selected
  range is written (and verified)

back to top

mem copy:

the function memcpy( p_dest, p_src, b_range ) is used to read max. 1Kbytes from the selected memory/io space to a buffer and then write it to the selected destination.

-select a range in the list box that should be copied to another location
-push source
-select the first location where the source block should be copied to
-push destination
-push mem copy

back to top

mem test:

the selected 1K range or the whole BAR space (asked by message box) is tested:
 the range is written with 0 (reset)
 the range is written with a counter value (every second value is inverted)
 the range is read and verified
 the number of errors are displayed in a message box
back to top

load file:

the content of the file is bytewise binary read from a file an written to the selected 1K range in the list box or to the whole BAR range.
back to top

save file:

the selected 1K range (or the whole BAR range) is bytewise binary dumped to a file
back to top


Concerns:


possible problems to get the BAR space:
----------------------------------------
> To: Mailing List Recipients <pci-sig-request@znyx.com
> Subject: Re: Unruly BIOSes and the Intel i960RP
>
>
>
> I had a problem with a Base Address Register in the Intel i960RP. The
> BIOS writes FFFF FFFF to this register and then reads what comes back to
> determine the size required by the device. The i960 returns a value
> based on the limit register once and once only, and subsequent reads
> from the BAR return the current programmed value of BAR. The PCI
> specification, as I read it, does not preclude this behaviour.
>
> It would seem to be more complicated to implement this behaviour as it
> requires a register to keep state information, and a side effect of
> reading in configuration space is to alter this state. Still, that is
> what happens, so I have to live with it.
>
> Some BIOSes, it seems, read the BAR twice when determining the address
> limit. Such BIOSes are confused by what they see come back, and so write
> 8000 8000 to the BAR. This seems to me equally bizarre. Surely 0000 0000
> would be a more sensible thing to write to a difficult BAR: this would
> effectively disable the allocation requested by that BAR ?
>
> I am considering writing a PCI configuration helper which runs after the
> BIOS but before Windows gets started, and straightens out anomolies such
> as the one above.
>
>
>

back to top