diff options
author | Ian Romanick <idr@us.ibm.com> | 2007-01-24 15:33:49 -0800 |
---|---|---|
committer | Ian Romanick <idr@us.ibm.com> | 2007-01-24 15:33:49 -0800 |
commit | 24506ea65be4cb29c5e1486aa0a529a40ce5c230 (patch) | |
tree | d9b6454d0c224135ce2bd5916c4b611d88b18a5e /hw/xfree86/int10/generic.c | |
parent | fdb3a0798f0d17e72ec7293d59a7a81b5ffdf95b (diff) |
Move xf86ReadLegacyBIOS to the one place that uses it.
xf86ReadLegacyBIOS is only used by one function in int10/generic.c.
Move a generic implementation of that function there, rename it to
read_legcay_BIOS, and delete all remnants of it from all other places.
Diffstat (limited to 'hw/xfree86/int10/generic.c')
-rw-r--r-- | hw/xfree86/int10/generic.c | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/hw/xfree86/int10/generic.c b/hw/xfree86/int10/generic.c index b3a946076..6a0471145 100644 --- a/hw/xfree86/int10/generic.c +++ b/hw/xfree86/int10/generic.c @@ -62,6 +62,60 @@ static void UnmapVRam(xf86Int10InfoPtr pInt); static void *sysMem = NULL; +/** + * Read legacy VGA video BIOS associated with specified domain. + * + * Attempts to read up to 128KiB of legacy VGA video BIOS. + * + * \return + * The number of bytes read on success or -1 on failure. + * + * \bug + * PCI ROMs can contain multiple BIOS images (e.g., OpenFirmware, x86 VGA, + * etc.). How do we know that \c pci_device_read_rom will return the + * legacy VGA BIOS image? + */ +static int +read_legacy_video_BIOS(struct pci_device *dev, unsigned char *Buf) +{ + const ADDRESS Base = 0xC0000; + const int Len = 0x10000 * 2; + const int pagemask = getpagesize() - 1; + const ADDRESS offset = Base & ~pagemask; + const unsigned long size = ((Base + Len + pagemask) & ~pagemask) - offset; + unsigned char *ptr, *src; + int len; + + + /* Try to use the civilized PCI interface first. + */ + if (pci_device_read_rom(dev, Buf) == 0) { + return dev->rom_size; + } + + ptr = xf86MapDomainMemory(-1, VIDMEM_READONLY, dev, offset, size); + + if (!ptr) + return -1; + + /* Using memcpy() here can hang the system */ + src = ptr + (Base - offset); + for (len = 0; len < (Len / 2); len++) { + Buf[len] = src[len]; + } + + if ((Buf[0] == 0x55) && (Buf[1] == 0xAA) && (Buf[2] > 0x80)) { + for ( /* empty */ ; len < Len; len++) { + Buf[len] = src[len]; + } + } + + xf86UnMapVidMem(-1, ptr, size); + + return Len; +} + + xf86Int10InfoPtr xf86ExtendedInitInt10(int entityIndex, int Flags) { @@ -216,7 +270,7 @@ xf86ExtendedInitInt10(int entityIndex, int Flags) */ vbiosMem = (char *)base + V_BIOS; (void)memset(vbiosMem, 0, 2 * V_BIOS_SIZE); - if (xf86ReadLegacyVideoBIOS(pInt->dev, vbiosMem) < V_BIOS_SIZE) { + if (read_legacy_video_BIOS(pInt->dev, vbiosMem) < V_BIOS_SIZE) { xf86DrvMsg(screen, X_WARNING, "Unable to retrieve all of segment 0x0C0000.\n"); } |