summaryrefslogtreecommitdiff
path: root/hw/xfree86/int10/generic.c
diff options
context:
space:
mode:
authorIan Romanick <idr@us.ibm.com>2007-01-24 15:33:49 -0800
committerIan Romanick <idr@us.ibm.com>2007-01-24 15:33:49 -0800
commit24506ea65be4cb29c5e1486aa0a529a40ce5c230 (patch)
treed9b6454d0c224135ce2bd5916c4b611d88b18a5e /hw/xfree86/int10/generic.c
parentfdb3a0798f0d17e72ec7293d59a7a81b5ffdf95b (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.c56
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");
}