On Sunday 15 July 2001 02:13, you wrote:
> I'm reading about PCI now. Downloaded the 440BX spec and ordered
> some docs also.
>
> The plan is to add PCI support to plex86, and I think also to
> modify the IO device plugin interface to work with the PCI
> support and be more modular/clean than it is currently.
>
> I want to split up the IO device emulation to work with
> the new interface, rather than be one big plugin.
>
> This would also allow better sharing between plex86 & bochs,
> if both projects use the same interface. (of course the
> implementation details are different)
>
> Any input on PCI welcome.
>
> -Kevin
Well...
PCI cards support possibly several different functions and plug into a "slot"
in a PCI bus. PCI busses can be cascaded with PCI bridges. PCI cards can
access I/O ports, interrupts and memory locations. They are also (or can be)
bus-mastering, which means that DMA engines on the card can write to PC
processor memory without the assistance of the processor. On the PC at least
(not in all architectures, though) the PCI addresses map into the physical
address space of the processor.
Access to PCI card resources from the PC side is controlled by a weird
construct called "configuration space". The configuration information for all
cards maps into configuration space. Each function has a page of
configuration information (256 bytes of data, total). So a byte of
information in configuration space is addressed by bus number, then slot
number, then function number, and finally offset withing page. There are two
(three?) methods of accessing configuration space, but only one of these ever
happens on a PCI. In this method, the full address (bus, slot, function,
offset) is written to a magic I/O port (0xCF8?) and then the four bytes based
at this address can be read or written through another magic location (0xCFC?
- these are the correct port addresses, but I'm not positive of the
address/data positions, though I think these are then).
The first sixteen bytes of the configuration page for a function (most cards
only have one function, function 0) contain a fixed header which includes
information like the Manufacturer ID (assigned on request by a standards
body), the Device ID (assigned by the manufacturer), the function number
(though you can't access this without knowing which fucntion you are
addressing - go figure!). The rest of the configuration page can take several
different standard forms, but typically have a set of "Base Address
Registers" first. These give the bus address and size of memory regions
accessible on the card (plus address and size of I/O port regions). These
regions are typically set up by the BIOS at startup and are not normally
changed during operation (though they can be remapped).
Thus the BARs give the locations on the cards (what they mean is defined by
the manufacturer and manufacturer information is required to make use of e.g
memory mapped registers).
The size of the region is in the BAR, but a trick must be used to obtain it.
The BAR will always align to a region of the required size, so if you write
"0xffffffff" to the BAR (saving the current value), a number of the bottom
bits will remain zero when you read the value back. The number of zeroes
indicates (with a little math) the size of the region - always a power of 2.
Is this enough to get you started?
Feel free to ask for more information/clarification where needed.
Colin
P.s. - yes, I am interested in working with you in this area.