PCI/BIOS/int10 handling in X.org
Jon Smirl
jonsmirl at gmail.com
Fri Jul 15 13:23:16 PDT 2005
On 7/15/05, Thomas Winischhofer <thomas at winischhofer.net> wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Jon Smirl wrote:
> > On the x86 the kernel is recording the boot device for you and it
> > supports shadow ROMs. There may need to be a parallel implementation
> > for other archs.
> >
> > There is also a kernel API for accessing the video ROM that knows
> > about the rom being shadowed, see drivers/pci/rom.c. This API is used
> > by the radeonfb driver, all fbdev drivers should be converted to it if
> > they are going to access the ROM.
>
> My current sisfb already does this.
>
> (OT: Besides, there is a bug in that code. The size of the ROM which is
> used to map the area is not checked against the byte from the ROM which
> is returned to the called as romsize. I have a case here where this byte
> is wrong: It says the BIOS is 64k, but in fact the BIOS is only 32k - as
> correctly shown by the pci resource length. You should at least check
> that the size info from the BIOS isn't bigger than the size of the area
> you mapped. If the caller uses the returned romsize to copy the BIOS
> image, this will lead to an Ooops.)
The people on the PCI list recommend this code to determine the size.
The size byte after the 55 AA is almost always wrong on ROMs that were
built for different platforms. The byte after 55 AA represents pages
and there is disagreement what the page size is.
from drivers/pci/rom.c
/*
* Try to find the true size of the ROM since sometimes the PCI window
* size is much larger than the actual size of the ROM.
* True size is important if the ROM is going to be copied.
*/
image = rom;
do {
void __iomem *pds;
/* Standard PCI ROMs start out with these bytes 55 AA */
if (readb(image) != 0x55)
break;
if (readb(image + 1) != 0xAA)
break;
/* get the PCI data structure and check its signature */
pds = image + readw(image + 24);
if (readb(pds) != 'P')
break;
if (readb(pds + 1) != 'C')
break;
if (readb(pds + 2) != 'I')
break;
if (readb(pds + 3) != 'R')
break;
last_image = readb(pds + 21) & 0x80;
/* this length is reliable */
image += readw(pds + 16) * 512;
} while (!last_image);
--
Jon Smirl
jonsmirl at gmail.com
More information about the xorg
mailing list