I have spent quite a bit of time investigating this issue and I think
we now understand the underlying issue.

The various places in XFree86 that mmap memory seem to very careful to
specify the proper mapping attributes, e.g. when mapping registers
with ordering requirements and side-effects (e.g. MMIO) the mapping is
forced to be non-cached and ordered. But ROM (e.g. device bios) can be
read cached, it has no side-effects. Thus when xf86ReadBIOS maps the
ROM BIOS it does not force a non-cached mapping. In theory this is
correct.

However on IA64 the concept of caching is overloaded, not only does it
refer to memory coherence but more importantly selects between two
vastly different memory spaces, RAM and IO. A cached access is
directed to RAM and a non-cached access is directed to IO (e.g. a pci
device).

It was observed that ROM reads using the standard VGA ROM base of
0xC0000 were successful, but ROM reads using a base address computed
from the PCI TAG (e.g. using the ROM BAR) failed unless the caching
attribute was asserted.

Note that at boot time the VGA bios is copied from the card to RAM at
0xC0000 (e.g. the shadow copy) as is required by the PCI spec. In
XFree86 it uses the symbol V_BIOS for this address.

This implies the following:

1) Reading the bios at 0xC0000 must be cached so that it is directed
to RAM.

2) Reading a bios on the card must be non-cached so that it becomes an
IO access.

This means if there is a common routine (e.g. xf86ReadBIOS) it must
distinguish between whether the base address is a shadow copy or
not. This also explains why cached reads of 0xC0000 were successful
and why cached reads off the card failed (and in most cases should
have machine checked). If our analysis is correct it means we can't
just force a non-cached mapping unless we know if we are pointing to a
shadow or the physical IO address of the bios.

This problem only seems to show up when there is a second graphics
card in the system. This also makes sense to me. The primary card has
its VGA shadowed at 0xC0000 in RAM. But if a driver or int10 code want
to read the bios on the non-primary card it can't use the VGA ROM base
because that belongs to the primary, it must get it from the PCI
config and read it from the card.

I went looking for the place in the XFree86 code that reads rom bios
using the tag, as this seems to be a key element, but I didn't find it
yet. Can someone point me at it?

On the assumption this analysis is correct should we ifdef
xf86ReadBIOS for __ia64__ and test for anything in the range of
0xC0000 to 0xC0000+size and modify the mapping based on that test?

Are there any places in the server which read BIOS that is not done
via the utility xf86ReadBIOS?

John


_______________________________________________
Devel mailing list
[EMAIL PROTECTED]
http://XFree86.Org/mailman/listinfo/devel

Reply via email to