home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: SysTools
/
SysTools.zip
/
pci040vk.zip
/
pci.doc
< prev
next >
Wrap
Text File
|
2000-05-29
|
27KB
|
555 lines
PCI - The PCI System information & Exploration tool.
The following is a somewhat rambling text, from which you should be able to
extract everything you ever wanted to know about this program! Please excuse my
poor documentation style; I really hate writing the docs :-)
■ General
This code is Written by Craig Hart in 1996-2000. It is released as freeware;
please use and modify at will. No guarantees are made or implied. Commercial
use is permitted.
I'd appreciate credit if you find this code useful. I'd also be interested to
see any code you may develop or modifications you create to this code...
suggestions & bug fixes are _always_ welcomed.
I can be reached by email: chart@hyperlink.net.au
See my home page for the latest version of all my software releases,
programmers information, updates for PCIDEVS.TXT and much more:
http://members.hyperlink.net.au/~chart
■ Why create this program, anyhow? What use is it? What does it do?
PCI basically produces a report of the PCI & AGP devices fitted to a PC,
including the system chipset. A plethoria of information is reported on,
including system resource useage (IRQs, DMAs, Memory ranges, etc),
busmastering, caching & device latencies, general capabilities and features,
subsystem info, and much more. A text-file PCIDEVS.TXT lists thousands of known
vendors, devices and subsystems, which PCI will refer to and display the info
from. PCI covers all PCI device derivitives, including PCI 64-bit & 66MHz
options, AGP (all speeds), CompactPCI, CardBus and PCI-X.
PCIDEVS.TXT is a plain text file, so you can update it yourself, however it is
updated regularly (virtually daily) by the author, and the latest revision is
always available as a free download from the webpage (see general section).
This program was originally written purely for me to learn how to program the
PCI BIOS found in newer PC's. Since then, this program has proven to be vastly
more useful, especially in the hands of a technician, system builder, and also
in the hands of those about to purchase or upgrade a PC.
To a technician or system builder, PCI can act as a system information and
diagnostic tool. It lists the resources devices have been assigned (for
example, IRQ's, Memory regions, etc) so it is handy for finding conflicts.
Because PCI also identifies the devices fitted, it is handy in figuring out
_exactly_ what drivers are required when setting up a system.
PC buyers don't need to open a PC to see exactly what they're getting: your
vendor can't tell you fibs about the chipset, graphic-card, or whatever, and
since the PC doesn't need to be opened to check what you ordered is what you
got fitted, you aren't loosing any warranties.
Second hand parts hoarders can figure out what they have, just by plugging it
in and running PCI - no more scratching your head over a mystery card you just
stumbled across amongst your latest piles of aquired junk. As above, finding
drivers becomes much easier when you can say *exactly* what brand model, and
revision of card you have.
To a programmer, PCI is a learning tool, since it's full source code is
supplied, and the dump configuration-space feature will help a programmer
discover how a driver alters the hardware to activate special features or
generally work with a given device.
■ Using PCI
Just run it. Read the output. Be happy!
Syntax: PCI [/H] [/D] [/S] [/T] [/B] [/P] [/?] ([] = optional)
Commandline parameters:
/H Use direct-hardware access to retrieve the information. Normally, the
system BIOS is called on to retrieve the information, however there are some
BIOS's (Some Award v4.51 on Intel 430FX Chipset, early Compaq's using the
Triflex Bridge chip) that incorrectly report some information. By bypassing the
BIOS, we can get the correct information. This only works if the BIOS uses
configuration mechanism 1. Mechanism 2 systems can use the BIOS method only.
Mechanism 2 systems are virtually non-existant as version 2.1 of the PCI
specifications insists on the use of mechanism 1 only.
/D Dump the PCI configuration space for each device. This option generates
a 256 byte hex-dump of the PCI configuration space for each detected device.
This is handy for people trying to learn to program a device, for those looking
to discover any 'extra' undocumented registers in a device, observe the changes
made by setup or driver software, and also to fault-find this program :-)
/S Produce summary report only. Lists vendors, devices, subsystem ID's
and IRQ's only. Usefull for when you need a "quick glance" and don't want to
wade through mountains of technical info. Still displays subsystem and IRQ
info, as these are typically the most-used features of PCI.
/T Disble the BIOS IRQ Routing table tests. May be usefull if PCI crashes
during this test, or you don't want to clutter up a device report with this
'extra' info.
/B List Bus, Device and Function info for each device. The bus number
tells you which PCI bus the device resides on (look at the PCI bridges to see
which bus number is 'created' by which bridge). The Device number is the PCI
device identifier for that device on that bus (there can be 32 devices on each
bus, and device numbers are generally non-contiguous). The function number is
the internal sub-funtion of that PCI CHIP (many devices are single-function and
only have a valid function 0, whilst others are multi-function and contain
several sub-functions; each device may have as many as 8 sub-functions).
/P Read and display PCI IRQ-router information. The IRQ router is the
device that connects the PCI slots INTA-INTD lines to the sytem's 16 IRQ lines.
The first part of this option shows what IRQ's are *potentially* available for
the BIOS to connect each PCI slot. If you see Slot 00, it's a motherboard
device, not a physical slot. You can work out which slot is which by using the
/B command line parameter to display the Device & Bus info for each card, and
then match this info up by looking physically at which card is in which slot.
Typically slots of the same bus run in order, either left to right, or right to
left; but different busses may be ordered differently to each other. Typically,
all slots of a given bus are physically next to each other rather than bieng
randomly distributed.
The second part of this option displays a table of slots and INTA-D link
values. To interpret this table, first note that a non-zero link value under
INTx means that that INTx pin on that PCI socket is wired to the IRQ router's
<number xx> input. A 00 means that INT line is not connected *at all*.
Let's look at a typical table:
SLOT BUS DEV INTA INTB INTC INTD
01 0 17 01 02 03 05
02 0 18 02 03 05 01
03 0 19 03 05 01 02
04 0 20 05 01 02 03
00 0 1 01 02 03 05
What this table tells us is that Slot 01 and Slot 00 share the SAME link
values, whilst the other 3 sockets each have different link values (under each
INT line). How is this important? Each *link value* is mapped to a system IRQ,
(but only if the PCI card signals that it requires an IRQ).
If Slot 00 and slot 01 are both populated (with cards that request an IRQ on
the same INT line), they will both be assigned the SAME IRQ! similarly, if a
card using INTD in Slot 2 and a card using INTB in slot 4 both require IRQ's,
they will each be configured to the same IRQ. Depending on your OS, this may or
may not be a good thing - some OS's don't support shared IRQs in this fashion
(A.K.A. the dreaded IRQ conflict) You may also want to know if you're going to
get an IRQ conflict if you're about to fit a new card and don't want to use
"trial and error" to get a non-shared IRQ assignment.
This table also highlights the other interesting points - if two slots have
different link values under the same INT line, they CANNOT be configured to the
SAME IRQ! Each slot will always be assigned a different IRQ from each other.
Also, once a link-value has been assigned an IRQ, all other slots where that
link value appears automatically take on that IRQ, so in many (but not all)
cases you can predict what IRQ you will get when you fit a card to that slot.
This sort of prediction an help in, for example, bulk-loading pre-configured
software images into mass-produced systems.
If you have IRQ assignment problems, these tables may highlight why - perhaps a
certain slot is incapable of having a desired IRQ assigned, or perhaps a given
slot has a certain INTx line not connected. Careful examination of these tables
will tell you straight away if this is the case or not.
The only thing this table won't tell you is which IRQ the BIOS will actually
assign each slot - there is no way to determine this and most BIOS's seem to
have no logical sequence for assigning resources; you get what you get! At
least PCI will tell you what the BIOS has done, and it's up to you to decide if
it's what you want, or not.
For more info, see also "PCI System Architecture" by Mindshare, inc. Chapter 11
has several diagrams (figures 11-4 and 11-5 in the third edition, pp216-217) of
IRQ router implementations that make this a lot easier to understand!
Finally, don't worry about the actual numerical link value (except for 00, of
course) - that only has meaning to the BIOS; all we're looking for is the
patterns the numbers represent, the numbers themselves are meaningless;
letters, cute pictures, roman numerals, colours, whatever! would serve the same
purpose just as well.
PCI's output can also be redirected (using MS-DOS pipes), for example to a
textfile on disk or a printer. IE "C:\>PCI > LOG" will generate a file on disk
called LOG. This is handy if you want to keep a perminant record of the system
under test, print it out, e-mail it to me, or whatever.
■ What's the ROM IRQ routing table and IRQ-router info?
The PCI ROM IRQ routing table is a scheme devised by Microsoft to assist
Windows Device Manager to reprogram PCI IRQs. It falls under the category of
'plug and play' support and is pretty much a vital component of any motherboard
these days. Normally, PCI IRQ's are set by the BIOS at boot time, and cannot be
changed after the system is booted.
Microsoft didn't like that and so they devised a mechanism to allows Windows to
change the IRQ assignments after boot-time. This makes sense, since Windows is
much more capable of handling scenarios like hot-docking (and the shuffling of
resources that this creates), that the BIOS clearly can't cope with in real
time or hope to forsee at boot time.
The IRQ-router info is a PCI BIOS call that predates the ROM IRQ routing table,
but offers similar information. The two should always agree! The disadvantage
of the BIOS call is primarily that it is slow, but also that it is based on the
very earliest versions of the PCI specifications, and thus lacks the
expandability and flexability of the newer ROM routing table, for future
growth.
The PCI standards say that the hardware vendors are free to connect PCI INT
lines to system IRQ's in any fashion they like; there is no "standard". Since
this is the case, Windows needs to know a few things such as which INT's can be
routed to which IRQs, which INT-to-IRQ mappings are fixed, and which INTs
belong exclusively to PCI. With that data in hand, Windows can re-configure
IRQs for PCI devices when/if required to resolve resource conflicts (in
conjunction with all the other resource data that Device Manager holds),
because the user has requested a specific resource setting, because of a
hot-dock event, Cardbus PC Card event, or whatever.
Only win95B (OSR2) or later supports this standard - Win95 original and OSR1
don't.... under 95A, PCI IRQ resources are fixed (Windows uses whatever the
BIOS assigned at boot time, and can't alter them) which is yet another reason
not to use 95A, if you still do! 95A is particularly lousy at managing any sort
of dockable/Cardbus equipped laptop.
The knowledge that the routing table(s) are present and valid is therefore
essential for determining why Windows is or is not correctly handling PCI IRQ
resoures. All modern motherboards should support the ROM routing table - but
many don't, or the table is faulty; PCI therefore is able to tell us at a
glance, wether IRQ management within windows is possible on that motherboard,
and wether the ROM table is in working order or not. I strongly suggest you
don't invest in any motherboard that has a non-existent or faulty
implementation of the ROM IRQ routing table. Needless to say, a dockable and/or
cardbus equipped laptop without a working routing table is going to be nothing
but trouble.
Many motherbards can gain (or fix bugs in) routing table support with a
FlashBIOS upgrade - visit your motherboard vendor's website (or
www.ping.be/bios) for the latest FlashBIOS and see if that helps. Complain
loudly to any vendor with a buggy routing table; with the advent of Win2000,
and the growing popularity of dockable laptops, this sort of thing is going to
be an absolute minimum requirement (along with ACPI support, for example) for a
true overall 'plug and play' operating environment.
■ Bugs, stuff yet to come, limitations, etc.
PCI is known to not operate under Windows NT or 2000. If you run NT/2000, you
must boot with DOS or Win95/98 to run PCI. This is because NT's HAL denies PCI
access to the system BIOS and I/O ports necssary for PCI to operate.
Basically, full decoding of all the PCI data is yet to be implemented... mainly
because I don't own a copy of the 'official' PCI specification documents, (And
I am unable to get them as they cost $$$ and I don't live in the USA so I have
no easy way to transmit payment...presuming I wanted to pay for them at all)
So, I am reliant on snippets of information collated from books, data sheets,
YOUR INPUT, etc etc. See the web page for more info, and the text of the next
section.
Having said that, PCI is now a very mature product (developed now for nearly 5
years) and it is 'virtually' complete. There isn't much left to do!
■ And to the PCI SIG:
Official PCI Programming information is not freely available. The controlling
body the "PCI Special Interest Group" has determined that documentation will be
made available to those willing to pay for it. And it's not cheap, or easily
obtainable outside the USA. I have the following to say to the PCI SIG:
Charging money for your documentation not only restricts programmers and end
users from adopting the PCI standard, but makes a mockery of the concept of
open information sharing that the Internet has always stood for. Rather than
take such a petty attitude towards Joe Average programmer, why not release your
documentation freely in electronic format? It can only help establish your
standards further.
Freely releasing formal documentation would also mean that programmers such as
myself can stop guessing about PCI, and stop writing up alternative
documentation that may ultimately be incorrect. I'm sure that the current host
of "third party" documentation (along with it's errors) can only make PCI look
BAD, not good.
Remember MCA? In 1987 we already had what PCI now offers.. please don't kill
PCI the same way IBM killed MCA.
■ How to "parse" PCIDEVS.TXT
Writing your own code to use my database? GREAT! You're more than welcome: the
database is freeware and you may use it for any purpose, including commercial
purposes. Here's how *I* parse the list, in "pseudocode". I hope this makes it
easier for you to write a parser too. Please forgive me if you think this is
poorly designed/could be done better; the technique stems from three things:
- Sourcefile is TEXT, not Binary, so there are no fixed field lengths.
- Many fields are optional so the catch-22 of "you dunno if it's there 'till
you read it, but once you've read it, you can't go back a line if it wasn't
what you expected" applies.
- The program has been added to and expanded "ad hoc" over a 5 year period.
Inevitable oversights and extensions have been dealt with several times.
- The basic file format can't be changed since there are many programs
(including a couple of commercial packages) relying on my file format not
changing.
Open the file as text (not binary) and read top to bottom, one line at a time.
1. Look for V entries, until you make a match to the vendor ID, or EOF in which
case report unknown vendor & device. Display Vendor Name.
<the file position pointer now points to the list of devices for that Vendor>
2. Read D entries until you get a match to the device ID, or hit another V
entry or EOF in which case stop and report unknown device. DONT display Device
Name yet!!
<the file position pointer now points to possible device revision records>
3. Read R entries until you get a match with the device's revision ID, or you
run out of R entries, or EOF. (There may be no R entries at all). If you match
R, then display that entry for the Device Name, otherwise display the Device
Name from the D entry... R is more accurate than D.
<the file position pointer now points to possible subsystem records>
4. If you matched D(and/or R), and the subsystem ID is <>00000000 then (look
for subsystem match):
in a loop, read a line, and
- try to match an X code with the 8 digit subsystem ID.
- try to match an O code with your subsystem vendor ID. Remember the
"generic" part description. Note the match, Keep going in this loop.
- try to match an S code with your subsystem device ID, but only if the O
code has already been matched.
exit when you matched an X code, or (matched an S AND an O code), EOF, or
you hit another V or D code.
- if you EOF or matched neither X, O nor S, report unknown subsystem ID.
- if you matched and X entry, report info next to X entry, and warn user this
is a known "oddball" device that has an otherwise invalid subsystem ID. (Ignore
any partial S-but-not-O match, if any - its a false alarm).
- if you matched O BUT NOT S, report the "generic" ID you remembered. Warn
user it may not be "fully" accurate, but is just a guestimation.
- if you matched O AND S, report info next to S entry; you exactly matched the
subsystem ID.
5. close list
6. If you have an O code, re-open the list. Scan list reading the V entries,
but try to match with the O code. This tells you the OEM name. Stop at match or
EOF. If EOF, report unknown OEM ID. Close list.
List must be closed and re-opened because the O name may be "higher" up the
list, thus a scan-to-the-end of the list will not match. This also means this
check must be done last since it causes us to "loose our spot" in the list.
Filepos() doesn't work (in Pascal, at least) since we're working with a
textfile!! (Argh!!)
If you find an invalid code letter, IGNORE IT; just move onto the next line.
This lets us add new code letters and not 'break' existing code.
■ Other formatting notes for PCIDEVS.TXT:
All useful lines are formatted thus:
<Code Letter><Tab><2-8 hex digits><tab><text>
You may NOT replace <tab> with <space>! Also, do NOT replace a tab with eight
spaces!!! the parser counts characters left to right, and looks for the tab
character, so wrong, extra or missing characters will result in a wrongly
parsed line. This means the file formatting must be kept strictly in check at
all times.
Overall, total line length must be 255 characters or less. Try to keep the text
under about 70 chars for display legibilty (excessive display wordwrap really
is in poor taste :-/)
All entries must always follow numerical order, lowest to highest. This makes
duplicates almost impossible when editing, but the parser doesn't actually
care, since it works on "keep looking until you run out" principle. A "tiny"
efficiency could be added by coding in "if database ID > our ID, give up" but I
hardly see the point, since the program runs faster than you can blink anyhow.
You should ignore all lines not starting with a valid code letter,tab sequence.
This allows clarity by inserting blank lines and comments wherever it may
please you. for clarity, begin comment lines with a <;> character; Accidental
capitilisation of the first word of a comment could lead to a wrongly parsed
code.
Valid Codes:
V Vendor ID. 4 digit hex number.
D Device ID. 4 digit hex number.
R Revision ID. 2 digit hex number.
X Incorrectly formatted susbsystem ID. 8 digit hex number.
O Subsystem OEM ID. 4 digit hex number. (top 16 bits of subsystem ID)
S Subsystem device ID. 4 digit hex number. (low 16 bits of subsystem ID)
The codes must always appear in this order in the file. Multiple O and S
entries may appear. O entries may appear without S entries. Only V and D
entries are required to identify a device - all others are optional and my be
omitted.
A note on R entries: R is NOT permitted under a subsystem entry. A chipset
revision is just that - the BASE CHIPSET's revision. The OEM can't have any
influence on the chipset's revision, since he doesn't make it! Thus, R is of no
use under the subsystem. I very much doubt any OEM has made two different model
cards by carefully buying different revision chips from the chipset vendor!!
A note on X entries: X entries are very rare. In the "early days" of subsystem
ID's, some vendors apparently thought they had carte blanche to put in any
number they liked. WRONG! However a few devices now exist with nonsensical
subsystem ID's like "55555555" or "F0F01234" and suchlike. X entries take care
of these few "oddball" devices. I don't expect to add any more than one or two
new X entries, ever.
** New code letters may be added from time to time, so your code should always
ignore any unknown code letters. This lets up expand the scope of the file
without 'breaking' existing code.
■ Program Revision Information
version 0.00ß : Initial private release: Didn't crash my home PC!
version 0.10ß : fixed bug whereby if either vendor byte is $FF, we would
skip the device. Ouch! Now finds devices reported as xxFF on
some buggy Award BIOS's chipsets. (Notibly, 80FF, not 8086
for the 82430FX IDE Ctrlr).
fixed problem decoding infotable[6].
fixed select timing decoding fixed irq=$ff decoding
version 0.11ß : fixed bug displaying select timing modes
version 0.12ß : added "subsystem id" information display
made cache line size display only if it exists (ie is<>0)
added /H parameter to use cfg mechanism 1, not BIOS to
read the hardware directly (gets around 80FF bug)
added bus mastering capability & latency reporting
added prefetchability reporting to memory ranges
fixed up several minor display and reporting issues
made IRQ display only if it's valid
version 0.13ß : fixed some display formatting bugs
subsystem ID's only displayed if valid (<>00000000)
Added subsystem recognition system (after many requests)
Added ability to direct output to a file ie "C:\>pci > log"
version 0.14ß : Added commandline parameter /D to dump device configuration
space, if required. This is usefull when programming a
PCI device, and/or looking for 'hidden' registers, features,
etc etc.
version 0.15ß : added subsystem vendor display; it's not always accurate,
(Some vendors are ignoring the rules) but when it is right,
it can be very useful.
Added capabilities list decoding & display - not yet tested!
Tidied up the code here and there - fixing my cruddy coding
fixed major bugs with Expansion ROM info display
fixed minor potential bug with I/O port decoding
added interface type to class code line
version 0.16ß : Fixed a stupid bug with new capabilities list display
Added raw-dump of Power Management capability data
version 0.17ß : fixed some minor display formatting problems
fixed several problems decoding type 2 headers
fixed another bug with expansion ROM decoding
added some more decoding of type 1 headers
added some more decoding of type 2 headers
added info on PCI IDE controllers & mode(s) of operation
added error checking for case of VENDORS.TXT missing
added some decoding of "power management" new capability
version 0.18ß : fixed display formatting bug with PCI IDE info
version 0.19ß : added IRQ summary to end of display
added generic subsystem ID detection & note
fixed compiler leaving debug-info in EXE
cleaned up a few minor display issues
version 0.20ß : added several new class codes intoduced with PCI spec v2.2
added decoding of command register
fixed "status 0200h ()" display formatting bug & redrew
the general layout of the Status info to avoid commom
wordwrap problem and to more correctly display timing +
busmaster info next to their "source" register
fixed "Number of PCI busses : 0"
version 0.21ß : added MSI Capability detection
added shared IRQ summary
indented capabilities listings to make them more readable
fixed error in classes.pas missing out the last few entries
added ExpROM decode for type 1 headers
added I/O port range decode for PCI Bridges
fixed display wordwrap problems
full decoding of Self Test function byte
version 0.30ß : converted to PCIDEVS.TXT format, added subsystem prediction
code
version 0.31ß : fixed slight bug with unknown subsystem vendor ID
added /S parameter for brief summary only report
changed IRQ reporting to reject bad IRQ values (0<IRQ<16)
this fixes runtime error 201 on compaq triflex bridge!
version 0.32ß : added revision ID decoding for more accurate chipset-id
added a load of info in the documentation on PCIDEVS.TXT
structure, parsing, etc
fixed problem with IRQ list wrong in summary mode because IDE
IRQs not recorded
Updated help to current featre set
version 0.33ß : added PCI IRQ Routing table Win9x compatibility tests
version 0.34ß : fixed some bugs in new routing table check routine
version 0.35ß : fixed capability pointer bug with type 1 headers
IRQ summary display formatting fixed
PCI major revision number leading 0 dropped
help page again fits into one 25 line screen
added display bus/device/function info option
version 0.40ß : added 'None' to "IRQ's dedicated to PCI" for when there are
truely none reported in the IRQ routing table info
added first attempt at PCI slot INTx routing data display
fixed a bug in "IRQ's dedicated to PCI" omitting IRQ 15
added latest PCI 2.2 class codes; fixed bugs in classes code
better error checking on AGP capability list
<EOF>