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.

Reply via email to