AGPGART related issue's in combination of ASUS motherboard

Bug #29813 reported by Amon_Re
12
This bug affects 1 person
Affects Status Importance Assigned to Milestone
linux-source-2.6.15 (Ubuntu)
Invalid
Medium
Unassigned

Bug Description

The following bug occurs in the last few kernels that have been released.

When using an Asus K8V-X SE motherboard, combined with an AMD Sempron 3200 AGP is incorrectly detected.

The problem manifests itself at boot with the agpgart incorrectly recognising the Aperture size.

Eg:

[4294680.541000] Linux agpgart interface v0.101 (c) Dave Jones
[4294680.555000] agpgart: Detected AGP bridge 0
[4294680.556000] agpgart: AGP aperture is 32M @ 0xe4000000

No matter of what Aperture size specified in the BIOS of the machine, the reported size is *ALWAYS* 32M.

The problem seems to manifest itself when trying to use DRI aswell as drivers from the manufacturers

DRI has been tested with 4 AGP cards sofar:
AGP ATI 9200
AGP ATI 9800
AGP ATI Rage128
AGP Nvidia MX240 (if i recall correctly, don't have the card handy right now)

X locks up with all 4 cards when DRI is enabled.

Once X locks up, the machine can't be accessed locally, only SSH access is possible.

I have run a program "agptest" who's source i found on the 'net, these are the results:

localhost ochal # ./test
version: 0.101
bridge id: 0x2821106
agp_mode: 0x1f000a1b
aper_base: 0xe4000000
aper_size: 32
pg_total: 112384
pg_system: 112384
pg_used: 0
entry.key : 0
entry.key : 1
Allocated 8 megs of GART memory
MemoryBenchmark: 8 mb/s
MemoryBenchmark: 8 mb/s
MemoryBenchmark: 9 mb/s
Average speed: 8 mb/s
Testing data integrity (1st pass): failed on first pass!
Testing data integrity (2nd pass): failed on second pass!

The source of the testprogam will be appended at the end of this report.

I am capable, and willing, of recompiling kernels, so do not hestitate to ask me to test stuff.

--------------------------------------------------

The following is the lspci output:
ochal@scruffy:~$ lspci
0000:00:00.0 Host bridge: VIA Technologies, Inc. K8T800Pro Host Bridge
0000:00:00.1 Host bridge: VIA Technologies, Inc. K8T800Pro Host Bridge
0000:00:00.2 Host bridge: VIA Technologies, Inc. K8T800Pro Host Bridge
0000:00:00.3 Host bridge: VIA Technologies, Inc. K8T800Pro Host Bridge
0000:00:00.4 Host bridge: VIA Technologies, Inc. K8T800Pro Host Bridge
0000:00:00.7 Host bridge: VIA Technologies, Inc. K8T800Pro Host Bridge
0000:00:01.0 PCI bridge: VIA Technologies, Inc. VT8237 PCI bridge [K8T800/K8T890 South]
0000:00:0c.0 Multimedia video controller: Brooktree Corporation Bt878 Video Capture (rev 11)
0000:00:0c.1 Multimedia controller: Brooktree Corporation Bt878 Audio Capture (rev 11)
0000:00:0d.0 USB Controller: ALi Corporation USB 1.1 Controller (rev 03)
0000:00:0d.1 USB Controller: ALi Corporation USB 1.1 Controller (rev 03)
0000:00:0d.3 USB Controller: ALi Corporation USB 2.0 Controller (rev 01)
0000:00:0d.4 FireWire (IEEE 1394): ALi Corporation M5253 P1394 OHCI 1.1 Controller
0000:00:0f.0 RAID bus controller: VIA Technologies, Inc. VIA VT6420 SATA RAID Controller (rev 80)
0000:00:0f.1 IDE interface: VIA Technologies, Inc. VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (rev 06)
0000:00:10.0 USB Controller: VIA Technologies, Inc. VT82xxxxx UHCI USB 1.1 Controller (rev 81)
0000:00:10.1 USB Controller: VIA Technologies, Inc. VT82xxxxx UHCI USB 1.1 Controller (rev 81)
0000:00:10.2 USB Controller: VIA Technologies, Inc. VT82xxxxx UHCI USB 1.1 Controller (rev 81)
0000:00:10.3 USB Controller: VIA Technologies, Inc. VT82xxxxx UHCI USB 1.1 Controller (rev 81)
0000:00:10.4 USB Controller: VIA Technologies, Inc. USB 2.0 (rev 86)
0000:00:11.0 ISA bridge: VIA Technologies, Inc. VT8237 ISA bridge [KT600/K8T800/K8T890 South]
0000:00:11.5 Multimedia audio controller: VIA Technologies, Inc. VT8233/A/8235/8237 AC97 Audio Controller (rev 60)
0000:00:12.0 Ethernet controller: VIA Technologies, Inc. VT6102 [Rhine-II] (rev 78)
0000:00:18.0 Host bridge: Advanced Micro Devices [AMD] K8 [Athlon64/Opteron] HyperTransport Technology Configuration
0000:00:18.1 Host bridge: Advanced Micro Devices [AMD] K8 [Athlon64/Opteron] Address Map
0000:00:18.2 Host bridge: Advanced Micro Devices [AMD] K8 [Athlon64/Opteron] DRAM Controller
0000:00:18.3 Host bridge: Advanced Micro Devices [AMD] K8 [Athlon64/Opteron] Miscellaneous Control
0000:01:00.0 VGA compatible controller: ATI Technologies Inc Radeon R300 ND [Radeon 9700 Pro]
0000:01:00.1 Display controller: ATI Technologies Inc Radeon R300 [Radeon 9700 Pro] (Secondary)

The testgart.c code:

/*
 *
 * Test program for AGPGART module under Linux
 *
 * Copyright (C) 1999 Jeff Hartmann,
 * Precision Insight, Inc., Xi Graphics, Inc.
 *
 */

#include <stdio.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <linux/types.h>
#include <linux/agpgart.h>
#include <asm/mtrr.h>
#include <errno.h>

unsigned char *gart;
int gartfd;
int mtrr;

int usec( void ) {
  struct timeval tv;
  struct timezone tz;

  gettimeofday( &tv, &tz );
  return (tv.tv_sec & 2047) * 1000000 + tv.tv_usec;
}

int MemoryBenchmark( void *buffer, int dwords ) {
  int i;
  int start, end;
  int mb;
  int *base;

  base = (int *)buffer;
  start = usec();
  for ( i = 0 ; i < dwords ; i += 8 ) {
    base[i] =
      base[i+1] =
      base[i+2] =
      base[i+3] =
      base[i+4] =
      base[i+5] =
      base[i+6] =
      base[i+7] = 0x15151515; /* dmapad nops */

  }
  end = usec();
  mb = ( (float)dwords / 0x40000 ) * 1000000 / (end - start);
  printf("MemoryBenchmark: %i mb/s\n", mb );
  return mb;
}

int insert_gart(int page, int size)
{
   agp_allocate entry;
   agp_bind bind;

   entry.type = 0;
   entry.pg_count = size;
#ifdef DEBUG
   printf("Using AGPIOC_ALLOCATE\n");
#endif
   if(ioctl(gartfd, AGPIOC_ALLOCATE, &entry) != 0)
    {
      perror("ioctl(AGPIOC_ALLOCATE)");
      exit(1);
    }

   bind.key = entry.key;
   bind.pg_start = page;
#ifdef DEBUG
   printf("Using AGPIOC_BIND\n");
#endif
   if(ioctl(gartfd, AGPIOC_BIND, &bind))
     {
        perror("ioctl(AGPIOC_BIND)");
        exit(1);
     }

   printf("entry.key : %i\n", entry.key);

   return(entry.key);
}

int unbind_gart(int key)
{
   agp_unbind unbind;

   unbind.key = key;
#ifdef DEBUG
   printf("Using AGPIOC_UNBIND\n");
#endif
   if(ioctl(gartfd, AGPIOC_UNBIND, &unbind) != 0)
     {
        perror("ioctl(AGPIOC_UNBIND)");
        exit(1);
     }

   return(0);
}

int bind_gart(int key, int page)
{
   agp_bind bind;

   bind.key = key;
   bind.pg_start = page;
#ifdef DEBUG
   printf("Using AGPIOC_BIND\n");
#endif
   if(ioctl(gartfd, AGPIOC_BIND, &bind) != 0)
     {
        perror("ioctl(AGPIOC_BIND)");
        exit(1);
     }

   return(0);
}

int remove_gart(int key)
{
#ifdef DEBUG
   printf("Using AGPIOC_DEALLOCATE\n");
#endif
  if(ioctl(gartfd, AGPIOC_DEALLOCATE, key) != 0)
    {
      perror("ioctl(GARTIOCREMOVE)");
      exit(1);
    }

   return(0);
}

void openmtrr(void)
{
   if ((mtrr = open("/proc/mtrr", O_WRONLY, 0)) == -1)
     {
        if (errno == ENOENT) {
           perror("/proc/mtrr not found: MTRR not enabled\n");
        } else {
           perror("Error opening /proc/mtrr:");
           perror("MTRR not enabled\n");
           exit(1);
        }
        return;
     }
}

int CoverRangeWithMTRR( int base, int range, int type )
{
   int count;

   /* set it if we aren't just checking the number */
   if ( type != -1 ) {
      struct mtrr_sentry sentry;

      sentry.base = base;
      sentry.size = range;
      sentry.type = type;

      if ( ioctl(mtrr, MTRRIOC_ADD_ENTRY, &sentry) == -1 ) {
         perror("mtrr");
         exit(1);
      }
   }

}

int init_agp(void)
{
   agp_info info;
   agp_setup setup;

#ifdef DEBUG
   printf("Using AGPIOC_ACQUIRE\n");
#endif
   if(ioctl(gartfd, AGPIOC_ACQUIRE) != 0)
     {
        perror("ioctl(AGPIOC_ACQUIRE)");
        exit(1);
     }
#ifdef DEBUG
   printf("Using AGPIOC_INFO\n");
#endif
   if(ioctl(gartfd, AGPIOC_INFO, &info) != 0)
     {
        perror("ioctl(AGPIOC_INFO)");
        exit(1);
     }

   printf("version: %i.%i\n", info.version.major, info.version.minor);
   printf("bridge id: 0x%lx\n", info.bridge_id);
   printf("agp_mode: 0x%lx\n", info.agp_mode);
   printf("aper_base: 0x%lx\n", info.aper_base);
   printf("aper_size: %i\n", info.aper_size);
   printf("pg_total: %i\n", info.pg_total);
   printf("pg_system: %i\n", info.pg_system);
   printf("pg_used: %i\n", info.pg_used);

   openmtrr();
   if (mtrr != -1) {
     CoverRangeWithMTRR(info.aper_base, info.aper_size * 0x100000,
       MTRR_TYPE_WRCOMB);
   }

   gart = mmap(NULL, info.aper_size * 0x100000, PROT_READ | PROT_WRITE, MAP_SHARED, gartfd, 0);

   if(gart == (unsigned char *) 0xffffffff)
     {
        perror("mmap");
        close(gartfd);
        exit(1);
     }

   setup.agp_mode = info.agp_mode;
#ifdef DEBUG
   printf("Using AGPIOC_SETUP\n");
#endif
   if(ioctl(gartfd, AGPIOC_SETUP, &setup) != 0)
     {
        perror("ioctl(AGPIOC_SETUP)");
        exit(1);
     }

   return(0);
}

int xchangeDummy;

void FlushWriteCombining( void ) {
        __asm__ volatile( " push %%eax ; xchg %%eax, %0 ; pop %%eax" : : "m" (xchangeDummy));
        __asm__ volatile( " push %%eax ; push %%ebx ; push %%ecx ; push %%edx ; movl $0,%%eax ; cpuid ; pop %%edx ; pop %%ecx ; pop %%ebx ; pop %%eax" : /* no outputs */ : /* no inputs */ );
}

void BenchMark()
{
  int i, worked = 1;

  i = MemoryBenchmark(gart, (1024 * 1024 * 4) / 4) +
    MemoryBenchmark(gart, (1024 * 1024 * 4) / 4) +
    MemoryBenchmark(gart, (1024 * 1024 * 4) / 4);

  printf("Average speed: %i mb/s\n", i /3);

  printf("Testing data integrity (1st pass): ");
  fflush(stdout);

  FlushWriteCombining();

  for (i=0; i < 8 * 0x100000; i++)
    {
      gart[i] = i % 256;
    }

  FlushWriteCombining();

  for (i=0; i < 8 * 0x100000; i++)
    {
       if(!(gart[i] == i % 256))
         {
#ifdef DEBUG
            printf("failed on %i, gart[i] = %i\n", i, gart[i]);
#endif
            worked = 0;
         }
    }

  if (!worked)
    printf("failed on first pass!\n");
  else
    printf("passed on first pass.\n");

   unbind_gart(0);
   unbind_gart(1);
   bind_gart(0, 0);
   bind_gart(1, 1024);

   worked = 1;
   printf("Testing data integrity (2nd pass): ");
   fflush(stdout);

   for (i=0; i < 8 * 0x100000; i++)
    {
       if(!(gart[i] == i % 256))
         {
#ifdef DEBUG
            printf("failed on %i, gart[i] = %i\n", i, gart[i]);
#endif
            worked = 0;
         }
    }

   if (!worked)
    printf("failed on second pass!\n");
  else
    printf("passed on second pass.\n");
}

int main()
{
   int i;
   int key;
   int key2;
   agp_info info;

   gartfd = open("/dev/agpgart", O_RDWR);
   if (gartfd == -1)
     {
        perror("open");
        exit(1);
     }

   init_agp();

   key = insert_gart(0, 1024);
   key2 = insert_gart(1024, 1024);

#ifdef DEBUG
   printf("Using AGPIOC_INFO\n");
   if(ioctl(gartfd, AGPIOC_INFO, &info) != 0)
     {
        perror("ioctl(AGPIOC_INFO)");
        exit(1);
     }

   printf("version: %i.%i\n", info.version.major, info.version.minor);
   printf("bridge id: 0x%lx\n", info.bridge_id);
   printf("agp_mode: 0x%lx\n", info.agp_mode);
   printf("aper_base: 0x%lx\n", info.aper_base);
   printf("aper_size: %i\n", info.aper_size);
   printf("pg_total: %i\n", info.pg_total);
   printf("pg_system: %i\n", info.pg_system);
   printf("pg_used: %i\n", info.pg_used);
#endif

   printf("Allocated 8 megs of GART memory\n");

   BenchMark();

   remove_gart(key);
   remove_gart(key2);

#ifdef DEBUG
   printf("Using AGPIOC_RELEASE\n");
#endif
   if(ioctl(gartfd, AGPIOC_RELEASE) != 0)
     {
        perror("ioctl(AGPIOC_RELEASE)");
        exit(1);
     }

   close(gartfd);
}

Revision history for this message
Amon_Re (ochal) wrote :

It seems they had the same issue's in FreeBSD.
Bug report is on this URL:

http://www.freebsd.org/cgi/query-pr.cgi?pr=88340

Revision history for this message
Amon_Re (ochal) wrote :

BIOS update 1203 (dated January 19th 2006) does not resolve the issue.

Revision history for this message
Ben Collins (ben-collins) wrote :

Everything I am looking at so far shows that this is a BIOS bug. The size comes from the PCI bios calls, which reads directly from system memory to get these sizes.

Try setting the aperture to 32M. If it doesn't work that way, then we can look at the DRI/AGP issues then.

Changed in linux-source-2.6.15:
status: Unconfirmed → Rejected
Revision history for this message
Amon_Re (ochal) wrote :

My first suspicions was also of a BIOS issue, but since the problem kept persisting through 3 BIOS versions (1000, 1003 & 1007 iirc) i'm suspecting it's something else.

I did replace this motherboard with another model though, wich works properly, so i won't be able to test it.

Setting aperture size to 32M didn't work neighter, was one of the first things i tried before bugging you guys ;)

If any dev living in Belgium wants to take a look at this issue/board, i might be willing to donate/lend/sell the board to him/her. (The board itself is still covered by it's warrenty)

Revision history for this message
Andre Moraes (andrelmoraes) wrote :

I've have this board running under Dapper 32-bits and I'm getting the same problem. I've set aperture to 32M doesn't works. However, Dapper AMD64 with k8 kernel detects and sets aperture correctly.

Revision history for this message
Andre Moraes (andrelmoraes) wrote :
Download full text (14.3 KiB)

I've tested with Debian Sarge 3.1r0 and agpgart was able to detected and set agp aperture correctly, with kernel 2.6.8-11-amd64-k8 Follows dmesg output from Debian:

Bootdata ok (command line is root=/dev/hdb1 ro )
Linux version 2.6.8-11-amd64-k8 (root@firetheft) (gcc version 3.4.4 20050314 (prerelease) (Debian 3.4.3-13)) #1 Mon May 30 22:15:15 UTC 2005
BIOS-provided physical RAM map:
 BIOS-e820: 0000000000000000 - 000000000009fc00 (usable)
 BIOS-e820: 000000000009fc00 - 00000000000a0000 (reserved)
 BIOS-e820: 00000000000e4000 - 0000000000100000 (reserved)
 BIOS-e820: 0000000000100000 - 000000003ffb0000 (usable)
 BIOS-e820: 000000003ffb0000 - 000000003ffc0000 (ACPI data)
 BIOS-e820: 000000003ffc0000 - 000000003fff0000 (ACPI NVS)
 BIOS-e820: 000000003fff0000 - 0000000040000000 (reserved)
 BIOS-e820: 00000000ff780000 - 0000000100000000 (reserved)
No mptable found.
On node 0 totalpages: 262064
  DMA zone: 4096 pages, LIFO batch:1
  Normal zone: 257968 pages, LIFO batch:16
  HighMem zone: 0 pages, LIFO batch:1
ACPI: RSDP (v000 ACPIAM ) @ 0x00000000000fab00
ACPI: RSDT (v001 A M I OEMRSDT 0x02000616 MSFT 0x00000097) @ 0x000000003ffb0000
ACPI: FADT (v001 A M I OEMFACP 0x02000616 MSFT 0x00000097) @ 0x000000003ffb0200
ACPI: MADT (v001 A M I OEMAPIC 0x02000616 MSFT 0x00000097) @ 0x000000003ffb0390
ACPI: OEMB (v001 A M I OEMBIOS 0x02000616 MSFT 0x00000097) @ 0x000000003ffc0040
ACPI: DSDT (v001 A0232 A0232008 0x00000008 MSFT 0x0100000d) @ 0x0000000000000000
ACPI: Local APIC address 0xfee00000
ACPI: LAPIC (acpi_id[0x01] lapic_id[0x00] enabled)
Processor #0 15:12 APIC version 16
ACPI: IOAPIC (id[0x01] address[0xfec00000] gsi_base[0])
IOAPIC[0]: Assigned apic_id 1
IOAPIC[0]: apic_id 1, version 3, address 0xfec00000, GSI 0-23
ACPI: INT_SRC_OVR (bus 0 bus_irq 0 global_irq 2 dfl dfl)
ACPI: IRQ0 used by override.
ACPI: IRQ2 used by override.
ACPI: IRQ9 used by override.
Using ACPI (MADT) for SMP configuration information
Checking aperture...
CPU 0: aperture @ e0000000 size 32 MB
Aperture from northbridge cpu 0 too small (32 MB)
AGP bridge at 00:00:00
Aperture from AGP @ e0000000 size 128 MB (APSIZE f20)
Built 1 zonelists
Kernel command line: root=/dev/hdb1 ro console=tty0
Initializing CPU#0
PID hash table entries: 16 (order 4: 256 bytes)
time.c: Using 1.193182 MHz PIT timer.
time.c: Detected 2000.101 MHz processor.
Console: colour VGA+ 80x25
Dentry cache hash table entries: 262144 (order: 9, 2097152 bytes)
Inode-cache hash table entries: 131072 (order: 8, 1048576 bytes)
Memory: 1023024k/1048256k available (1586k kernel code, 24460k reserved, 901k data, 124k init)
Calibrating delay loop... 3923.96 BogoMIPS
Security Scaffold v1.0.0 initialized
Capability LSM initialized
Mount-cache hash table entries: 256 (order: 0, 4096 bytes)
CPU: L1 I Cache: 64K (64 bytes/line), D cache 64K (64 bytes/line)
CPU: L2 Cache: 512K (64 bytes/line)
CPU: AMD Athlon(tm) 64 Processor 3000+ stepping 02
Using local APIC NMI watchdog using perfctr0
ENABLING IO-APIC IRQs
init IO_APIC IRQs
 IO-APIC (apicid-pin) 1-0, 1-16, 1-17, 1-18, 1-19, 1-20, 1-21, 1-22, 1-23 not connected.
..TIMER: v...

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.